gpt4 book ai didi

php - Nginx/PHP FPM 优雅停止 (SIGQUIT) : not so graceful

转载 作者:IT王子 更新时间:2023-10-29 00:06:05 25 4
gpt4 key购买 nike

运行 nginx 1.9.*/PHP 7.0.*(但在 5.6.* 中也有完全相同的行为)

尝试在维护期间优雅地停止 PHP-FPM/nginx 组合以关闭节点。为此,我将 SIGQUIT 发送到 php-fpm,它应该提供正常关闭。

为了测试这个,我做了一个愚蠢的脚本

<?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

期望:在任何进行中的请求中间,当请求正常关闭时,当前请求应该完成,但任何其他请求都应该失败。

不幸的是,当我尝试通过向 PHP-FPM 主进程发送 SIGQUIT ( http://manpages.ubuntu.com/manpages/precise/man8/php5-fpm.8.html) 来触发此行为时:

kill -s SIGQUIT $FPMPID

连接立即断开,导致 ngnix 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

process_control_timeout

Time limit for child processes to wait for a reaction on signals from master

基本上,通过将其设置为 10s 之类的值,子进程将等待那么长时间,同时在退出之前处理现有请求。

不幸的是,php-fpm 主进程似乎立即退出,因此,受代码启发 here ,我写了一个包装脚本:

#!/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 文件被删除(大概是被其中一个子进程删除了?我仍然不清楚如何它被删除)。

无论如何,这个包装器脚本作为我们使用 Kubernetes 运行的 php-fpm docker 容器的 CMD 运行良好。

关于php - Nginx/PHP FPM 优雅停止 (SIGQUIT) : not so graceful,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36564074/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com