当前位置: 首页 > 后端技术 > PHP

关于php-fpmreload会取消正在处理的请求的解决方法

时间:2023-03-29 13:42:44 PHP

开始测试,发现php-fpmreload会强制kill正在处理的请求。上网查了下,发现其他人也有这个问题,报到官网:https://bugs.php.net/bug.php?id=75440和https://bugs.php.net/bug.php?id=60961,帖子是2017年和2012年的,还没??解决。官方帮助手册也说reload是graceful的,哈哈哈,不要太信了:manphp-fpm...SIGINT,SIGTERMimmediateterminationSIGQUITgracefulstopSIGUSR1re-openlogfileSIGUSR2gracefulreloadofallworkers+reloadoffpm配置文件/二进制文件。..reload流程介绍php-fpm是masterworker的工作方式。php-fpm主进程通过接受用户发送的SIGUSR2信号实现自身服务的reload:kill-USR2主进程(master进程)收到reload信号后会向所有子进程发送SIGGUIT信号,同时注册定时器时间。timeout的值为fpm_global_config.process_control_timeout。如果子进程在指定时间内没有结束,则子进程将被杀死。比如设置超时值为1秒,如果1秒内还没有结束,就会直接给子进程发送SIGKILL信号,强制其杀掉。最后等待所有子进程结束后,master根据之前保存的启动参数重启一个进程,并继承父进程的socket文件描述符。注意,这只是一种缓解方案,仍然不能保证请求不会丢失。这个解决办法在于配置选项process_control_timeout,配置文件在php-fpm.conf(我的在/usr/local/etc/php-fpm.conf),默认值为0,子进程会被杀死立即,这里我将其更改为60s进行测试:;子进程等待对来自主进程的信号作出反应的时间限制。可用单位:s(秒)、m(分)、h(我们的)或d(天);默认单位:秒;DefaultValue:0process_control_timeout=60s测试结果,只要正在处理的请求在这个时间内完成,就可以正常返回。这不是100%的解决方案,因为master进程要等到所有的子进程都结束后才能重新创建worker进程,而在process_control_timeout等待的时候,worker进程不接受请求,所以这期间新的请求是进不来的。新请求将由fpm排队。如果nginx超时,会报502给用户。为了安全起见,nginx的超时值应该是process_control_timeout值的两倍。尽管可能会报告502,但这比终止正在进行的请求更容易接受。总结尽管设置了process_control_timeout,除此之外,PHP-FPM在重新加载完成之前不会为新请求提供服务。但是,所有这些新请求将由fpm排队并在重新加载完成后立即执行。最终用户的结果是他们在此期间看到浏览器显示加载。还有一点,设置的超时时间并不能保证请求一定会在这个时间内得到处理。程序员还是有必要保证自己脚本的运行时间在一个合理的范围内。