博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于php-fpm与nginx进程重载的坑
阅读量:6863 次
发布时间:2019-06-26

本文共 9880 字,大约阅读时间需要 32 分钟。

背景

今天下午发布了一个统计功能,发现线上机器没有mongo模块,于是使用phpize编译了mongo模块,再用kill -HUP 进程号重启进程
于是乎,以前都没有问题的操作,导致了php-fpm进程全部挂掉了。

现象

1、执行操作

ps -ef|grep php-fpmroot     20749     1  0 Jun15 ?        00:06:04 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)nobody   24144 20749  0 Nov16 ?        00:00:16 php-fpm: pool www

执行重启操作

kill -HUP 20749

 

这里没有输出任何东西, 再查看,发现进程挂了

于是试着重启

[root@gameyeah_my ~]# /usr/local/php/sbin/php-fpm[18-Nov-2016 21:39:26] ERROR: unable to bind listening socket for address '127.0.0.1:9000': Address already in use (98)[18-Nov-2016 21:39:26] ERROR: FPM initialization failed

发现端口已经被使用,但是明明 fast-cgi没有运行了啊。

于是netstat -nalt|grep 9000,得出一个OA进程占有,这个就很奇怪了。
暂时不明。
2、解决
把OA进程kill掉后,重启发现报错

[root@gameyeah_my ~]# /etc/init.d/php-fpm restartGracefully shutting down php-fpm /etc/init.d/php-fpm: line 82: kill: (20749) - No such process.........

查看php-fpm的pid文件,还存在。 这个是异常关闭进程导致的,需要手动删除,再重启 -> OK了.

3、再次出现问题
环境一样,我再次使用kill -HUP 进程号 再次出现php-fpm master进程挂掉,但是子进程都还存在
没办法,只好pkill php-fpm再使用/usr/local/php/sbin/php-fpm重启, 好, 又正常了。

研究

参考线上朋友的说明:
用HUP信号使Nginx加载新的配置文件 当Nginx接收到HUP信号的时候,它会尝试着去解析并应用这个配置文件,如果没有问题,那么它会创建新的worker进程,并发送信号给旧的 worker进程,让其优雅的退出。 接收到信号的旧的worker进程会关闭监听socket,但是还会处理当前的请求,处理完请求之后,旧的 worker进程退出。
查看使用yum安装的php-fpm的reload控制脚本

reload () {        echo -n $"Reloading $prog: "        if ! /usr/sbin/php-fpm --test ; then                RETVAL=6                echo $"not reloading due to configuration syntax error"                failure $"not reloading $prog due to configuration syntax error"        else                killproc -p ${pidfile} php-fpm -USR2        ## 或者 kill -USR2 `cat $php_fpm_PID`                RETVAL=$?        fi        echo}

发现官方是使用-USR2 平滑reload的

网上这位朋友说明如下:
当你想升级Nginx到一个新的版本,增加或减少module的时候 发送USR2信号给master进程。master进程会把自己的.pid文件重命名为.oldbin(例 如,/usr/local/nginx/logs/nginx.pid.oldbin),然后执行新的二进制文件,从而启动一个新的master进程和新的worker进程.
为了验证-HUP与-USR2的区别,做实验(回狗窝后自己机器):
1、php.ini添加上mongo.so, 使用-HUP重启,发现master进程真挂了

[root@gameyeah_my mongo-php-driver-legacy]# /usr/local/php/sbin/php-fpm -t[18-Nov-2016 23:02:01] NOTICE: configuration file /usr/local/php/etc/php-fpm.conf test is successful[root@gameyeah_my mongo-php-driver-legacy]# ps -ef|grep phproot     10411 29694  0 22:53 pts/2    00:00:00 vim php_nginx_reload.mdroot     10415 29717  0 22:56 pts/3    00:00:00 grep --colour=always phproot     29860     1  0 21:56 ?        00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)                                                                    nobody   29861 29860  0 21:56 ?        00:00:01 php-fpm: pool www                                                                                                            nobody   29862 29860  0 21:56 ?        00:00:02 php-fpm: pool www                                                                                                            nobody   29908 29860  0 22:03 ?        00:00:01 php-fpm: pool www                                                                                                            [root@gameyeah_my mongo-php-driver-legacy]# kill -HUP 29860[root@gameyeah_my mongo-php-driver-legacy]# ps -ef|grep phproot     10411 29694  0 22:53 pts/2    00:00:00 vim php_nginx_reload.mdroot     10417 29717  0 22:56 pts/3    00:00:00 grep --colour=always phpnobody   29861     1  0 21:56 ?        00:00:01 php-fpm: pool www                                                                                                            nobody   29862     1  0 21:56 ?        00:00:02 php-fpm: pool www                                                                                                            nobody   29908     1  0 22:03 ?        00:00:01 php-fpm: pool www

只好重启

[root@gameyeah_my mongo-php-driver-legacy]# pkill php-fpm ; /usr/local/php/sbin/php-fpm

 

2、php.ini添加上mongo.so, 使用-USR2重启, 发现一切正常进程号更新; 使用phpinfo()查看mongo模块正常使用.

[root@gameyeah_my mongo-php-driver-legacy]# ps -ef|grep phproot     10411 29694  0 22:53 pts/2    00:00:00 vim php_nginx_reload.mdroot     10476     1  0 23:03 ?        00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)nobody   10477 10476  0 23:03 ?        00:00:00 php-fpm: pool www          nobody   10478 10476  0 23:03 ?        00:00:00 php-fpm: pool www          root     10480 29717  0 23:03 pts/3    00:00:00 grep --colour=always php[root@gameyeah_my mongo-php-driver-legacy]# kill -USR2 10476[root@gameyeah_my mongo-php-driver-legacy]# ps -ef|grep php root     10411 29694  0 22:53 pts/2    00:00:00 vim php_nginx_reload.mdroot     10481     1  0 23:05 ?        00:00:00 php-fpm: master process (/usr/local/php/etc/php-fpm.conf)nobody   10482 10481  0 23:05 ?        00:00:00 php-fpm: pool www          nobody   10483 10481  0 23:05 ?        00:00:00 php-fpm: pool www          root     10485 29717  0 23:05 pts/3    00:00:00 grep --colour=always php

 

3、修改php.ini, 不添加mongo.so,使用 -HUP重启 --- master进程一样关闭了,只留下子进程

4、重置,不添加mongo.so,使用 -USR2重启 --- 一切正常

5、我重新以不修改php.ini的方式分别以-HUP/-USR2尝试重启,现象与上面一样
1) 使用kill -HUP pid ,master进程关闭,没有成功启动新的master进程
2) 使用kill -USR2 pid, 旧master进程关闭,新的master进程成功启动

6、是不是php-fpm的特有性质呢??于是改试nginx进程
1) 使用-HUP重启, 发现修改的配置生效了,但是进程号未修改

[root@gameyeah_my mongo-php-driver-legacy]# cat /usr/local/nginx/logs/nginx.pid 26220[root@gameyeah_my mongo-php-driver-legacy]# kill -HUP `cat /usr/local/nginx/logs/nginx.pid`[root@gameyeah_my mongo-php-driver-legacy]# ps -ef|grep nginxnobody    5852 19372  0 Apr10 ?        00:00:48 nginx: worker process                                                    nobody    5853 19372  0 Apr10 ?        00:00:30 nginx: cache manager process                                             root     10411 29694  0 22:53 pts/2    00:00:00 vim php_nginx_reload.mdwww      10543 26220  0 23:22 ?        00:00:00 nginx: worker process                                          www      10544 26220  0 23:22 ?        00:00:00 nginx: worker process                                          www      10545 26220  0 23:22 ?        00:00:00 nginx: worker process                                          www      10546 26220  0 23:22 ?        00:00:00 nginx: worker process                                          root     10548 29717  0 23:22 pts/3    00:00:00 grep --colour=always nginxroot     19372     1  0 Apr08 ?        00:00:00 nginx: master process /usr/local/nginx-rtmp/sbin/nginx -c /usr/local/nginx-rtmp/conf/nginx.confroot     26220     1  0 Apr15 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf[root@gameyeah_my mongo-php-driver-legacy]# cat /usr/local/nginx/logs/nginx.pid 26220

2) 使用-USR2重启,发现新的master进程起来了,旧的master进程还存在;再使用-QUIT关闭旧进程(-WINCH一样没有见关闭),过一段时间发现旧进程真没了.

[root@gameyeah_my mongo-php-driver-legacy]# kill -USR2 `cat /usr/local/nginx/logs/nginx.pid`   [root@gameyeah_my mongo-php-driver-legacy]# ps -ef|grep nginx                               nobody    5852 19372  0 Apr10 ?        00:00:48 nginx: worker process                                                    nobody    5853 19372  0 Apr10 ?        00:00:30 nginx: cache manager process                                             root     10411 29694  0 22:53 pts/2    00:00:00 vim php_nginx_reload.mdwww      10543 26220  0 23:22 ?        00:00:00 nginx: worker process                                          www      10544 26220  0 23:22 ?        00:00:00 nginx: worker process                                          www      10545 26220  0 23:22 ?        00:00:00 nginx: worker process                                          www      10546 26220  0 23:22 ?        00:00:00 nginx: worker process                                          root     10551 26220  0 23:23 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.confwww      10552 10551  0 23:23 ?        00:00:00 nginx: worker process                                          www      10553 10551  0 23:23 ?        00:00:00 nginx: worker process                                          www      10554 10551  0 23:23 ?        00:00:00 nginx: worker process                                          www      10555 10551  0 23:23 ?        00:00:00 nginx: worker process                                          root     10557 29717  0 23:23 pts/3    00:00:00 grep --colour=always nginxroot     19372     1  0 Apr08 ?        00:00:00 nginx: master process /usr/local/nginx-rtmp/sbin/nginx -c /usr/local/nginx-rtmp/conf/nginx.confroot     26220     1  0 Apr15 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

真心查看nginx官方提供的reload方法是使用-HUP

reload() {    echo -n $"Reloading $prog: "    killproc -p ${pidfile} ${prog} -HUP    RETVAL=$?    echo}

结论

php-fpm与nginx的使用-USR2/-HUP意义不一样!
Master进程能够接收并处理如下的信号:
TERM, INT(快速退出,当前的请求不执行完成就退出)
QUIT (优雅退出,执行完当前的请求后退出)
HUP (重新加载配置文件,用新的配置文件启动新worker进程,并优雅的关闭旧的worker进程, 用于nginx的加载新配置,不能用于php-fpm加载新配置)
USR1 (重新打开日志文件)
USR2 (平滑的升级nginx二进制文件/平滑加载php-fpm新配置)
WINCH (优雅的关闭worker进程)
于是 可以自己写php-fpm控制脚本

 

关闭

kill -QUIT `cat $php_fpm_PID`

平滑重载配置

kill -USR2 `cat $php_fpm_PID`

强制关闭

kill -TERM `cat $php_fpm_PID`

 

可以自己写nginx控制脚本

关闭

kill -QUIT `cat /usr/local/nginx/logs/nginx.pid`

平滑重载配置

kill -HUP `cat /usr/local/nginx/logs/nginx.pid`

平滑升级nginx,即升级新编译的nginx

OldPid=`cat /usr/local/nginx/logs/nginx.pid`kill -USR2 $OldPidkill -QUIT $OldPid--------------------------------------------upgrade() {oldbinpidfile=${pidfile}.oldbinconfigtest -q || returnecho -n $"Starting new master $prog: "killproc -p ${pidfile} ${prog} -USR2echofor i in `/usr/bin/seq $UPGRADEWAITLOOPS`; do    /bin/usleep $SLEEPMSEC    if [ -f ${oldbinpidfile} -a -f ${pidfile} ]; then        echo -n $"Graceful shutdown of old $prog: "        killproc -p ${oldbinpidfile} ${prog} -QUIT        RETVAL=$?        echo        return    fidoneecho $"Upgrade failed!"RETVAL=1}

 

转载自:http://gameyeah.net/blog/php_nginx_reload.html 《》

转载于:https://www.cnblogs.com/wpjamer/articles/6819485.html

你可能感兴趣的文章
Excel打印质量引起的异常及解决方案
查看>>
2.GET与POST的区别
查看>>
tyvj1172自然数拆分
查看>>
Makefile <网络转载>
查看>>
IO流的应用————小型资源管理器
查看>>
C++输入输出流格式控制(转)
查看>>
【C++】C++中的string类的用法总结
查看>>
new pc
查看>>
zabbix之 zabbix server 跟 agent 更换ip地址
查看>>
WebAPI 实现前后端分离的示例
查看>>
自控力极差的人如何自救?
查看>>
java中高级面试题整理及参考答案
查看>>
冯·若依曼体系结构
查看>>
B00009 C语言分割字符串库函数strtok
查看>>
windows查看端口占用命令[转]
查看>>
基于 canvas 将图片转化成字符画
查看>>
python内置函数整理
查看>>
ORACLE忘记sys密码
查看>>
CSDN V5 CSDN统一天下
查看>>
经典排序算法 - 鸽巢排序Pigeonhole sort
查看>>