我们可以重新加载其中一个PHP-FPM池而不会打扰其他人

时间:2013-06-03 06:09:29

标签: php

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

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

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

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

我还要感谢任何其他可以让我拥有所需池管理的配置建议

2 个答案:

答案 0 :(得分:39)

php-fpm允许正常重启子节点,通常在init脚本上使用reload关键字而不是restart,发送USR2信号。

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

  • 清空APC缓存
  • 更改日志文件路径
  • alter min / max / start child settings

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

如果要确保在重新加载其中一个池时永远不会重新加载其他池,则必须管理多个php-fpm守护程序和每个守护程序一个池。这意味着要编写几个init脚本和主配置文件。

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

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

答案 1 :(得分:1)

尽管已经有了最佳答案,但我在写这篇文章是为了提供更多最佳答案所遗漏的信息。

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

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

  • 当停机时间为零时,延迟处理计数吗?
  • 服务器可以排队多少个请求?
  • 当然,延迟处理意味着该页面将卡在用户端。