解决nginx502错误经验小结

好久木有码字了,都有点生疏了。之前有写过一篇文章《解决nginx中FastCGI的502 Bad Gateway错误》,本篇《解决nginx502错误经验小结》就当是正冰对上一篇文章的补充与完善。

首先先讲理论,理论就跟说明书一样,理解明白了下次遇到问题可以快速判断,举一反三:

LNMP架构中PHP是运行在FastCGI模式下,随着系统的运行,php-cgi进程所占用的内存越来越多,并且似乎只增不减。有一段时间当我所管理的VPS经常遇到nginx 502错误时候,我以为这是网站访问量过高或者是系统中有软件配置不当出现问题。但是多番数据比较发现网站访问量并不高,配置也并未做修改。内存占用越大,不得不考虑是不是内存泄漏(这个是linux系统比较特有的),而来自PHP官方的解释却说php-cgi进程并没有内存泄漏,php-cgi会在每个请求结束的时候会回收脚本使用的全部内存,但是并不会释放给操作系统,而是继续持有以应对下一次PHP请求。这样做大概是为了减少内存碎片化或者解决从系统申请内存之后又释放回操作系统所需要的时间不可控问题。可是如果偶然一次PHP请求使用了诸如ftp或者zlib这样的大内存操作,那么将导致一大块系统内存被php-cgi持续占有,不能被利用。 

下面先来说一下php-cgi配置文件php-fpm.conf中较为有用的2个参数方便下面解决方案的说明:max_children与max_requests。max_children参数表示php将开启多少个php-cgi的子进程来应对用户的请求,而max_requests参数表示每个children最多处理多少个请求后便会被管理进程关闭“释放”内存后启动应对下一次PHP请求。php把请求轮询给每个children,在大流量下,每个childre到达max_requests所用的时间都差不多,这样就使得所有的php-cgi子进程基本上在相近时间被关闭并重启。在这期间,nginx无法将php文件转交给php-fpm处理,所以cpu会降低(不用处理php,更不用执行sql),而负载会升高(关闭和开启children、nginx等待php-fpm),网卡流量也降低(nginx无法生成数据传输给客户端)。

讲完理论继续讲实践,实践检验真理:

我用一条语句来说明php-cgi的内存占用情况以及进程启动时间

ps -e -o 'pid,comm,args,pcpu,rsz,vsz,stime,user,uid'|grep www|sort -nrk5

图中显示的就是10个php-cgi进程,每个进程目前内存占用在10-16M左右(随着时间推移会越来越大直至进程重启内存回收),进程的上一次启动时间在12点52分到12点59分间。

php-cgi内存占用大.jpg

大小: 43.06 K
尺寸: 300 x 76
浏览: 347 次
点击打开新窗口浏览全图

最后,给出本篇小结:

解决方法:适当提高children的数值,降低max_requests的数值。建议一般VPS的children在5-10,max_requests在1000-2000,具体自行调整。 对了,降低max_requests的数值可使php-cgi重启的周期缩短,偶然的高内存操作造成的问题影响时间也会缩短。

还有另外一个解决方法:写一个crontab脚本,定时发现高内存占用的php-cgi进程并向它传送kill指令。 正冰只写出来提供思路,不推荐大家采用,因为当你在kill某个高内存占用的进程时,也就同时kill了该进程当前在处理的用户请求。根据正冰测试跟踪nginx的web日志发现当kill进程产生会出现502错误,因为该请求并未由php-cgi完成。所以,慎用该方法。

造成nginx产生502错误的原因较多,但是无非也就这么几方面:php-cgi进程数不够用、php执行时间长、php-cgi进程死掉等等。

遇到问题多查一下日志信息,相信寻因解决问题会很容易。Good Luck!

Tags: nginx, fastcgi, 502

上一篇: CentOS Linux下安装VNC
下一篇: 845主板支持最大2G內存,安裝3根512M的,只识别1G?

相关文章

发表评论