windows 服务器下的 apache 出现 MemoryError (django wsgi )

用django开发的一个老项目,开发时版本是0.9 , 后期服务器迁移多次,现在django版本用的1.2,用的apache 配合 wsgi模块搭建,原来服务器是linux,目前移到了 windows server 2012 配置是 2 cpu, 8g mem

昨天客户说服务器出问题了,访问时出现 500错误,internal server error

登录到服务器,打开apache的日志,发现和以前的不一样,并没有指出程序什么地方出错,截取一段如下

[Fri Sep 22 09:38:02 2029] [error] [client xxx.xxx.xxx.xxx]     args[0] = force_unicode(args[0]), referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:02 2029] [error] [client xxx.xxx.xxx.xxx]   File "D:\\Python27\\lib\\site-packages\\django\\utils\\encoding.py", line 85, in force_unicode, referer: http://xx.xxx.xx.xx/xxxx/index/
[Fri Sep 22 09:38:02 2029] [error] [client xxx.xxx.xxx.xxx]     s = s.decode(encoding, errors), referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:02 2029] [error] [client xxx.xxx.xxx.xxx]   File "D:\\Python27\\Lib\\encodings\\utf_8.py", line 16, in decode, referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:02 2029] [error] [client xxx.xxx.xxx.xxx]     return codecs.utf_8_decode(input, errors, True), referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:02 2029] [error] [client xxx.xxx.xxx.xxx] TemplateSyntaxError: Caught MemoryError while rendering: , referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:04 2029] [error] [client xxx.xxx.xxx.xxx] mod_wsgi (pid=4308): Exception occurred processing WSGI script 'D:/mytest/wsgi/mytest.wsgi'., referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:04 2029] [error] [client xxx.xxx.xxx.xxx] Traceback (most recent call last):, referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:04 2029] [error] [client xxx.xxx.xxx.xxx]   File "D:\\Python27\\lib\\site-packages\\django\\http\\__init__.py", line 431, in next, referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:04 2029] [error] [client xxx.xxx.xxx.xxx]     chunk = chunk.encode(self._charset), referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:04 2029] [error] [client xxx.xxx.xxx.xxx]   File "D:\\Python27\\lib\\site-packages\\django\\utils\\functional.py", line 55, in _curried, referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:04 2029] [error] [client xxx.xxx.xxx.xxx]     return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs)), referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:04 2029] [error] [client xxx.xxx.xxx.xxx]   File "D:\\Python27\\lib\\site-packages\\django\\utils\\safestring.py", line 81, in _proxy_method, referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:04 2029] [error] [client xxx.xxx.xxx.xxx]     data = method(self, *args, **kwargs), referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/
[Fri Sep 22 09:38:04 2029] [error] [client xxx.xxx.xxx.xxx] MemoryError, referer: http://xx.xxx.xx.xx/xxxx/xxxx/index/

MemoryError ? 这是说内存错误?

查看任务管理器后发现内存使用近4G, 离8G的内存还远着,再看apache使用了近2G, 尝试将 apache 服务重新启动了一下,发现apache内存使用将到了 25M。而原来出现错误的页面都已经正常。

联想到新增加了视频上传功能,猜测可能是用户最近上传视频之后,导致了apache的内存泄漏。

联想到前段时间一台云服务器1cpu, 1g mem 出现的内存不足问题,先对apache进行配置调节。

五.启用MPM模块配置文件
1.MPM模块是专门针对Windows操作系统而优化设计的,在Apace安装目录下的conf下的httpd.conf文件中启用该配置文件
找到
# Server-pool management (MPM specific)

Include conf/extra/httpd-mpm.conf (去掉前面的注释符号"#")
2.在Apace安装目录下的conf下extra目录中的配置文件httpd-mpm.conf中更改MPM模块的相关配置
找到mpm_winnt_module,由于mpm_winnt模块只会创建1个子进程,因此这里对单个子进程的参数设置就相当于对整个Apache的参数设置。
<IfModule mpm_winnt_module>

ThreadsPerChild 1500

MaxRequestsPerChild 0

</IfModule>
ThreadsPerChild: 线程数量,线程数量越大,越能够更好的处理更多并发连接。默认值是150,推荐设置:小型网站=1000 中型网站=1000~2000 大型网站=2000~3500
MaxConnectionsPerChild:累计最多处理到多少个请求,超过该值会自动重启Apache,设置为0,则没有限制,但可能会照成内存泄漏。小型网站=10000 中型或大型网站=20000~100000,若设置为大于0时,最好为ThreadsPerChild的100倍

MaxConnectionsPerChild:累计最多处理到多少个请求,超过该值会自动重启Apache,设置为0,则没有限制,但可能会照成内存泄漏。小型网站=10000 中型或大型网站=20000~100000,若设置为大于0时,最好为ThreadsPerChild的100倍

考虑到内部系统,将参数调小一点,观察一下将来是否正常。
#ThreadsPerChild 150
#MaxRequestsPerChild 0

ThreadsPerChild 100
MaxRequestsPerChild 5000

参考: https://blog.csdn.net/xyy1028/article/details/89440858

远程桌面连接windows server时出现错误“由于安全设置错误, 客户端无法连接到远程计算机,请确认您连接到网络”

登录一个内网堡垒机时,出现错误提示 “由于安全设置错误, 客户端无法连接到远程计算机,请确认您连接到网络”。

其他人能用够正常连接,应该是本机设置问题,不是服务器配置问题

1:关闭本机的防病毒,防火墙后,还是无效

2:网络是通的,估计还是系统的安全配置问题。

Step 1:打开”本地安全策略”- Win+R 并输入 secpol.msc (或者在”管理工具”中打开);

Step 2:在本地安全策略中,打开“本地策略”下的“安全选项”;

            在右边的策略中,找到“系统加密:将FIPS算法用于加密 、哈希和签名”点击右键属性

            将“本地安全设置”设置为“已禁用”,在单击“应用”,后”确定”,即可远程控制!

设置完成后,顺利远程连接!

ref: https://blog.csdn.net/weixin_33724046/article/details/91727244

引入的js或css文件后面跟的问号如?20200202是起什么作用的

修改程序的样式,发现好像没有起作用,查看网页源码,发现css后还跟着?20191101,这样的东东。

<link rel="stylesheet" type="text/css" href="http://localhost/static/vendor/layui/extend/layui-form-autocomplete/autocomplete.css?20191101">

度娘了一下,又长知识了

css和js带参数(形如.css?v=与.js?v=)   使用参数有两种可能:

第一、脚本并不存在,而是服务端动态生成的,因此带了个版本号。  

第二、这种情况更常见。用于对付客户端缓存,防止客户端会缓存css和js文件,每次升级js或css文件后,都改变版本号,强制客户端浏览器重新下载新的js或css文件 。

版本号,可以是日期值,也可以是一个递增的值版本值,大版本小版本的方式,或者根据脚本的生成时间书写,比如 20080727182553 就是精确到了生成脚本的秒,而 2.3.3 就是大版本小版本的方式。

所以修改好样式之后 ,顺便把css的版本号修改一下,这样子样式就能更新成功。

为了减少一个个文件里面修改版本号,通常可以定义一个常量,css与js引用这个常量,如果有修改时直接改常量值就可以。如:

defined('RESOURCE_STATIC_TIMESTAMP') OR define('RESOURCE_STATIC_TIMESTAMP', 20200815); // 引入静态资源使用的时间戳

<link rel="stylesheet" type="text/css" href="<?php echo base_url('static/autocomplete.css').'?'.RESOURCE_STATIC_TIMESTAMP; ?>">


参考:
https://www.cnblogs.com/yaoqj/p/4094424.html

云服务器居然内存不足(只有apache,mysql)

一台小服务器,前几天出现持续地连接不上数据库的情况。

于是进到服务器,重启mysql, 过一会发现,依然连不上,mysql又崩了,查看mysql日志

[Note] InnoDB: PUNCH HOLE support available
[Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
[Note] InnoDB: Uses event mutexes
[Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
[Note] InnoDB: Compressed tables use zlib 1.2.11
[Note] InnoDB: Using Linux native AIO
[Note] InnoDB: Number of pools: 1
[Note] InnoDB: Using CPU crc32 instructions
[Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
[ERROR] InnoDB: mmap(137428992 bytes) failed; errno 12
[ERROR] InnoDB: Cannot allocate memory for the buffer pool
[ERROR] InnoDB: Plugin initialization aborted with error Generic error
[ERROR] Plugin ‘InnoDB’ init function returned error.
[ERROR] Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed.
[ERROR] Failed to initialize builtin plugins.
[ERROR] Aborting

[Note] Binlog end
[Note] Shutting down plugin ‘CSV’
[Note] /usr/sbin/mysqld: Shutdown complete

有问题找度娘,结果人家说是 mysql 没有使用swap

$ free
total used free shared buff/cache available
Mem: 1009152 243408 561672 24052 204072 599100
Swap: 0 0 0

好像还真是

于是给系统加上swap

$ sudo fallocate -l 1G /swapfile
$ ls -lh /swapfile
-rw-r–r– 1 root root 1.0G Aug 6 00:34 /swapfile
$ sudo chmod 600 /swapfile
$ ls -lh /swapfile
-rw——- 1 root root 1.0G Aug 6 00:34 /swapfile
$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=acf7347a-7a96-443b-ae73-cf6ea2d6e7f2
$ sudo swapon /swapfile
$ sudo swapon –show
NAME TYPE SIZE USED PRIO
/swapfile file 1024M 0B -2
$ free -h
total used free shared buff/cache available
Mem: 985M 240M 541M 23M 203M 582M
Swap: 1.0G 0B 1.0G

重启mysql,貌似有点作用,不过发现还是好慢好慢,访问在等待十几分钟后可以显示出网页,

top – 02:09:49 up 1:11, 2 users, load average: 0.23, 0.10, 0.02
Tasks: 117 total, 2 running, 80 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 1.0 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.0 hi, 0.3 si, 0.0 st
KiB Mem : 1009280 total, 301684 free, 399268 used, 308328 buff/cache
KiB Swap: 2097148 total, 1963260 free, 133888 used. 447072 avail Mem

$ free
total used free shared buff/cache available
Mem: 1009280 399296 301480 19832 308504 447044
Swap: 2097148 133888 1963260

看看 apache的配置,稍微调整一下,还是不起作用

<IfModule mpm_prefork_module>
        StartServers                    3
        MinSpareServers          2
        MaxSpareServers         5
        #MaxRequestWorkers        150
        MaxRequestWorkers        20
        #MaxConnectionsPerChild   5000
        MaxConnectionsPerChild   30
</IfModule>

应该是apache吃了太多的内存,导致mysql吃不到,然后mysql直接掀桌子不玩。

短时间内没辙了,还是云服务器加内存吧

原来服务器是活动时买的,1cpu 1G,想要升到2G内存,因为不加钱,居然不给升,发企鹅工单后,才知道只有产生了费用的才给升,于是升到4G。

升好内存后,发现世界原来如此美好,一切又美出天了

这世界归根结底还是人民币玩家厉害。

空下来研究一下apache的内存调优,或者切换到nginx上

参考:

ubuntu 18.04 设置swap 交换分区文件:https://blog.csdn.net/lhs960124/article/details/80446433

禁止回车提交表单

项目里用了太多的弹层,还有太多的逻辑判断,要提交到不同的 action

结果发现一个问题,某个弹层内直接回车时表单就被提交了,省略了中间好多的逻辑判断什么的

决定先暂时把这个回车禁用掉,后期再来修复功能

自动提交情况说明:

默认情况下,单个输入框,无论按钮的type="submit"还是type="button"类型,回车即提交。
当type="submit"时,无论有几个type="text"输入框,回车均表示提交。(<button>按钮默认的type为submit)
当type="button"时,且存在多个输入框,回车不提交。(button)

网上查了下,处理办法有如下二种

1:解决单个输入框的回车即提交问题,可以增加一个隐藏的input="text" display='none'; 然后 type 类型为 button 。

2:在 form 表单或 input 中加入:onkeydown="if(event.keyCode==13){return false;}"

决定还是使用第二种,现在各种库用得太多,反而不直观。直接onkeydown,以后代码查起来清晰一点