我们可以在不打扰其他人的情况下重新加载其中一个PHP-FPM池吗?

php
2022-08-30 11:32:35

我为同一台主机提供了多个PHP-FPM UNIX套接字池,以具有代码库/功能的逻辑分离,并解决将来相同的扩展问题。Nginx根据URI模式管理到正确套接字的路由。部署工作正常。

每当我更改任何一个的池配置时,我都会重新加载/重新启动FPM进程(通过USR2信号)。

我不知道FPM的内部是如何工作的,但我假设当我重新启动主进程时,所有池都会重新启动/重新加载。如果我错了,请纠正我。

我想知道当其他人按原样工作时,我是否只能重新加载/重新启动一个池(这些池上正在进行的事务没有问题)。

我也很感激任何其他配置建议,可以让我有想要的池管理


答案 1

php-fpm允许优雅地重新启动子代码,通常使用关键字而不是在 init 脚本上,发送 USR2 信号。reloadrestart

因此,通过执行正常的重新启动,您不应该丢失任何正在运行的事务。在对每个孩子的当前请求管理结束后,这些孩子被杀死。如果您不需要真正的重新启动,这应该足够了。我做了一些测试,例如,重新加载就足以:

  • 清空 APC 缓存
  • 更改日志文件路径
  • 更改最小/最大/启动子项设置

所以我没有发现需要真正重启的情况。除了重新加载无法启动已停止的服务

如果你想确保其他池永远不会被重新加载,当你想要重新加载其中一个,你将不得不管理几个php-fpm守护进程和每个守护进程一个池。这意味着编写多个初始化脚本和主配置文件。

使用 restart 关键字更危险,特别是因为 init 脚本可能会在停止步骤中杀死长时间运行的孩子。使用多个PID和配置文件管理多个守护程序,您甚至可以获得带有选项的命令(debian中就是这种情况),这将杀死所有运行相同php-fpm可执行文件的守护程序(如果您运行多个php-fpm进程,则在停止具有正确PID的正确守护程序后,有效地将kill -9发送到所有其他并行php-fpm守护程序, 这是非常糟糕的)。start-stop-daemon--exec

因此,必须使用reload关键字(USR2信号)。


答案 2

虽然已经有一个最好的答案,但我写这篇文章是为了提供从最好的答案中遗漏的更多信息。

  • 执行重新加载后,PHP-FPM 将等待所有请求得到处理,但不会超过 process_control_timeout。如果达到process_control_timeout,将发生502错误
  • 在等待所有请求处理完毕时,PHP-FPM 不会处理任何新请求,而是将它们排队。因为只有在处理完所有旧请求后,才会创建新的重新加载的进程。

这导致了一些事实和问题:

  • 当说零停机时间时,延迟处理是否算数?
  • 服务器能够排队多少个请求?
  • 当然,延迟处理意味着页面会卡在用户端。

推荐