前言
大家是否发现本站前段时间访问非常缓慢?因为网站程序从万网免费空间迁到的阿里云 ECS 上,而数据库还留在万网空间,数据库就是远程访问,造成数据库查询速度十分慢。最近将数据库迁到了 ECS 上,速度也杠杠的,平均处理时间都低于 1 秒,访问量也有所增加。但是随着访问量的增加,PHP-FPM 撑不住了,基本上一个多小时就炸,导致 Nginx 连接不上 PHP-FPM,发生 502 错误,只有重启 PHP-FPM 才能解决。问题是没有理由整天去看他有没有炸啊对不对,于是我便开始了搜索折腾之旅。
上网一搜,好像这个问题也挺普遍的,大部分解决方案都是增加系统内核连接数、PHP 队列最大任务数(好像是这么叫吧,不清楚),不过似乎并没有什么卵用,该 502 的还是照样 502。经过我的多次实践,现在给出我的解决方案。
解决方案
增加 PHP-FPM 子进程数
使用 sudo netstat -napo |grep "php-fpm" | wc -l
来查看当前运行的 PHP-FPM 子进程数。
打开 /etc/php5/fpm/pool.d/www.conf
找到下面的内容
; The number of child processes to be created when pm is set to 'static' and the ; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. ; This value sets the limit on the number of simultaneous requests that will be ; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. ; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP ; CGI. The below defaults are based on a server without much resources. Don't ; forget to tweak pm.* to fit your needs. ; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' ; Note: This value is mandatory. pm.max_children = 5
如果正在运行的数量已经达到或者接近最大数量,将 pm.max_children
改为 50
。我认为这是个比较合适的值,不过要注意单个 PHP-FPM 进程的内存占用,避免内存不足造成尴尬。
另外,在配置 pm = dynamic
的情况下,适当的提高 pm.start_servers
、pm.min_spare_servers
和 pm.max_spare_servers
的数值也是不错的方法,这里不做建议,请移步这里。
; The number of child processes created on startup. ; Note: Used only when pm is set to 'dynamic' ; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 pm.start_servers = 2 ; The desired minimum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' pm.min_spare_servers = 1 ; The desired maximum number of idle server processes. ; Note: Used only when pm is set to 'dynamic' ; Note: Mandatory when pm is set to 'dynamic' pm.max_spare_servers = 3
定时重启 PHP-FPM
定时重启 PHP-FPM 是一个保持 PHP-FPM 稳定运行的好方法,我设置的是每天 3:00 重启一次,我使用 cron 定时执行重启命令(我是在 ubuntu 环境下)
编辑定时任务文件
sudo crontab -e
添加下行
0 3 * * * service php5-fpm restart
[v_warn]不保证所有的 PHP-FPM 重启命令都一致,请自行尝试[/v_warn]
将 TCP 切换为 UNIX 域套接字
UNIX 域套接字相比 TCP 套接字在 loopback 接口上能提供更好的性能(更少的数据拷贝和上下文切换)。
但有一点需要牢记:仅运行在同一台服务器上的程序可以访问UNIX域套接字(显然没有网络支持)。
同样打开 /etc/php5/fpm/pool.d/www.conf
找到 listen = ...
,修改为 listen = /dev/shm/php5-fpm.sock
同时修改 Nginx 的 fastcgi_pass
。fastcgi_pass unix:/dev/shm/php5-fpm.sock;
结语
修改完配置记得保存。这个方案我还没来得及检验就发出来了,不保证一定有效,更多方法请看这里。
发表回复