最新消息:觉得本站不错的话 记得收藏哦 博客内某些功能仅供测试 讨论群:135931704 快养不起小站了 各位有闲钱就打赏下把 My Email weicots#gmail.com Please replace # with @

关于由PHP-CGI进程导致nginx502错误 以及 php-fpm参数优化 小结

LINX ajiang-tuzi 1717浏览


首先我们先来了解下什么是关于什么是CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI?

php-fpm参数优化

php-fpm进程设置多少合适,设成动态还是静态?
下面是摘自Google讨论话题:《 PHP-FPM on highload tips 》[墙外,出去看了下貌似消失了]。
When you running a highload website with PHP-FPM via FastCGI, the following tips may be useful to you
如果你的高负载网站使用PHP-FPM管理FastCGI,也许下面这些技巧对你有用
1. Compile PHP’s modules as less as possible, the simple the best (fast);
尽量少安装PHP模块,最简单是最好(快)的
2. Increas PHP FastCGI child number to 100 and even more. Sometime, 200 is OK! ( On 4GB memory server);
把你的PHP FastCGI子进程数调到100或以上,在4G内存的服务器上200就可以(建议压力测试来得出自己服务器合理的值)
3. Using SOCKET PHP FastCGI, and put into /dev/shm on Linux;
socket连接FastCGI,/dev/shm是内存文件系统,socket放在内存中肯定会快些
4. Increase Linux “max open files”, using the following command (must be root):
Linux下增加文件打开数,命令如下:

cat >> /etc/security/limits.conf <<EOF
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
EOF

5. Increase PHP-FPM open file description rlimit:
增加 PHP-FPM 打开文件描述符的限制:

# vi $php_install_dir/etc/php-fpm.conf
rlimit_files = 51200

6. Using PHP code accelerator, e.g eAccelerator, XCache. And set “cache_dir” to /dev/shm on Linux.
使用php代码加速器,例如 eAccelerator, XCache.在Linux平台上可以把`cache_dir`指向 /dev/shm
/usr/local/php/etc/php-fpm.conf重要优化参数详解:

pm = dynamic

pm参数指定了进程管理方式,有两种可供选择:static或dynamic,从字面意思不难理解,为静态或动态方式。如果是静态方式,那么在php-fpm启动的时候就创建了指定数目的进程,在运行过程中不会再有变化(并不是真的就永远不变);而动态的则在运行过程中动态调整,当然并不是无限制的创建新进程,受pm.max_spare_servers参数影响;动态适合小内存机器,灵活分配进程,省内存。静态适用于大内存机器,动态创建回收进程对服务器资源也是一种消耗

pm.max_children = 24

static模式下创建的子进程数或dynamic模式下同一时刻允许最大的php-fpm子进程数量

pm.start_servers = 16

#动态方式下的起始php-fpm进程数量

pm.min_spare_servers = 12

#动态方式下服务器空闲时最小php-fpm进程数量

pm.max_spare_servers = 24

#动态方式下服务器空闲时最大php-fpm进程数量
一般php-fpm进程占用20~30m左右的内存就按30m算。如果单独跑php-fpm,动态方式起始值可设置物理内存Mem/30M,由于大家一般Nginx、MySQL都在一台机器上,于是预留一半给它们,即php-fpm进程数为$Mem/2/30。
LNMP在一台机器上参数(仅供参考,建议压力测试得出):

Mem=`free -m | awk '/Mem:/{print $2}'` #我的机器内存是987M
sed -i "s@^pm.max_children.*@pm.max_children = $(($Mem/2/20))@" $php_install_dir/etc/php-fpm.conf
sed -i "s@^pm.start_servers.*@pm.start_servers = $(($Mem/2/30))@" $php_install_dir/etc/php-fpm.conf
sed -i "s@^pm.min_spare_servers.*@pm.min_spare_servers = $(($Mem/2/40))@" $php_install_dir/etc/php-fpm.conf
sed -i "s@^pm.max_spare_servers.*@pm.max_spare_servers = $(($Mem/2/20))@" $php_install_dir/etc/php-fpm.conf

987M内存:

pm = dynamic
pm.max_children = 24
pm.start_servers = 16
pm.min_spare_servers = 12
pm.max_spare_servers = 24

关于 nginx502错误经验小结-PHP-CGI进程

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

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

php-cgi内存占用大

[root@weicot ~]# ps -e -o pid,comm,args,pcpu,rsz,vsz,stime,user,uid  | grep www|sort -nrk5
 3702 grep            grep --color=auto www        0.0   960 112660 23:34 root         0
 2806 php-fpm         php-fpm: pool www            0.0  7992 572060 22:12 nginx     1000
 2805 php-fpm         php-fpm: pool www            0.0  7992 572060 22:12 nginx     1000
 2804 php-fpm         php-fpm: pool www            0.0  7992 572060 22:12 nginx     1000
 2803 php-fpm         php-fpm: pool www            0.0  7992 572060 22:12 nginx     1000
 2802 php-fpm         php-fpm: pool www            0.0  7992 572060 22:12 nginx     1000
[root@weicot ~]# date
2016年 03月 14日 星期一 23:34:11 CST

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

解决方法:适当提高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错误的原因较多,但是无非也就这么几方面:

解决nginx502错误经验小结
进程数不够用、php执行时间长、php-cgi进程死掉等等。
备注及引用
本文整理自互联网 仅供学习和交流使用
参考:
运维博客

转载请注明:(●--●) Hello.My Weicot » 关于由PHP-CGI进程导致nginx502错误 以及 php-fpm参数优化 小结