运行 nginx 1.9.* / PHP 7.0.* (但 5.6.* 中的行为也完全相同)
尝试优雅地停止 PHP-FPM / nginx 组合以在维护期间关闭节点。为此,我将 SIGQUIT 发送到 php-fpm,这should提供优雅的关闭。
为了测试这一点,我做了一个愚蠢的脚本
<?php sleep(5); echo 'done';
使用以下curl在本地进行测试
curl -I x.x.x.x:8080
通常会产生输出:
HTTP/1.1 200 OK
Server: nginx
Date: Tue, 12 Apr 2016 04:48:00 GMT
Content-Type: text/html; charset=UTF-8
Connection: close
期望:在任何正在进行的请求中间,当请求正常关闭时,当前请求应该完成,但任何其他请求都应该失败。
不幸的是,当我尝试通过发送 SIGQUIT (http://manpages.ubuntu.com/manpages/precise/man8/php5-fpm.8.html http://manpages.ubuntu.com/manpages/precise/man8/php5-fpm.8.html) 到 PHP-FPM 主进程:
kill -s SIGQUIT $FPMPID
连接立即地下降,导致 nginx 502
HTTP/1.1 502 Bad Gateway
Server: nginx
Date: Tue, 12 Apr 2016 04:48:07 GMT
Content-Type: text/html
Content-Length: 166
Connection: close
有什么建议吗?我很想让系统的这一部分尽可能无缝。谢谢!
在与同样的情况斗争了一段时间后,我相信我已经找到了神奇的配置设置,可以使子进程在死亡之前完成处理请求。
http://php.net/manual/en/install.fpm.configuration.php#process-control-timeout http://php.net/manual/en/install.fpm.configuration.php#process-control-timeout
进程控制超时
子进程等待主进程信号反应的时间限制
基本上,通过将其设置为类似的东西10s
,子进程将等待那么长时间,同时在退出之前处理现有请求。
不幸的是,似乎php-fpm
master进程立即退出,所以,受到代码的启发here https://github.com/php/php-src/blob/1c295d4a9ac78fcc2f77d6695987598bb7abcb83/sapi/fpm/init.d.php-fpm.in,我写了一个包装脚本:
#!/bin/bash
PHP_FPM_PID='/php-fpm.pid'
wait_for_pid () {
try=0
while test $try -lt 35 ; do
if [ ! -f "$1" ] ; then
try=''
break
fi
echo -n .
try=`expr $try + 1`
sleep 1
done
}
function clean_up {
echo "Killing $(cat $PHP_FPM_PID)"
kill -QUIT `cat $PHP_FPM_PID`
wait_for_pid $PHP_FPM_PID
echo "Done!"
exit 0
}
trap clean_up EXIT
nohup php-fpm --daemonize --pid $PHP_FPM_PID 2>&1 &
while true; do sleep 1; done
# ^ do nothing forever
它等待 35 秒或直到该 pid 文件被删除(大概是由子进程之一删除?我仍然不清楚how它已被删除)。
无论如何,这个包装脚本工作得很好CMD
为了我们的php-fpm
我们使用 Kubernetes 运行的 docker 容器。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)