![为什么 php-fpm 在 Kubernetes 中始终有一个工作进程按需运行](https://linux22.com/image/794293/%E4%B8%BA%E4%BB%80%E4%B9%88%20php-fpm%20%E5%9C%A8%20Kubernetes%20%E4%B8%AD%E5%A7%8B%E7%BB%88%E6%9C%89%E4%B8%80%E4%B8%AA%E5%B7%A5%E4%BD%9C%E8%BF%9B%E7%A8%8B%E6%8C%89%E9%9C%80%E8%BF%90%E8%A1%8C.png)
我们在 Kubernetes 中运行 php-fpm 容器。这是一个测试设置,因此为了节省资源,php-fpm (8.1) 配置如下:
pm = ondemand
pm.max_children = 5
pm.max_requests = 1000
应用程序未在使用中(例如,没有对应用程序的请求,访问日志中没有任何内容)。但是,此池中始终有一个工作进程在运行。
问题:我怎样才能找出导致 php-fpm 产生这个 worker 的原因?
我看过的东西:
- netstat:php-fpm:主进程监听端口 9000,并连接到两个 unix 套接字(即 stdout 和 stderr),没有其他内容
- 访问日志:空
- 配置:pm.min_spare_servers 设置为 1(默认值),但配置文件指出这仅用于“动态”调度程序
- 当在 Kubernetes 之外使用相同配置运行 php-fpm 时,当站点处于空闲状态时,不会生成任何子进程(或所有子进程都退出)
答案1
你的分析是正确的。你看到一个工作进程在 php-fpm 容器中运行,原因是按需流程管理器和pm.min_spare_servers不设置为 1 很可能由于按需模式的默认行为。
在 ondemand 模式下,工作进程仅在响应请求时启动。但是,它会无限期地维持一个工作进程的存在,以处理可能增加的流量或初始请求。这可以防止每个请求都从头开始。
pm.min_spare_servers正如您所提到的,这些设置仅适用于动态进程管理器,它会预先分叉一定数量的工作进程以使其准备就绪。它不会影响按需行为。
虽然在当前情况下可能没有外部原因导致生成此工作进程。但在测试环境中,使用按需模式保持一个工作进程处于活动状态是一种合理的方法,可以平衡资源节约与处理潜在的流量增加。
考虑静态模式对于生产,如果您将此设置移至生产并了解预期的流量模式,请考虑使用静态进程管理器。此模式根据您的配置启动固定数量的工作进程。(例如:pm.max_children)
考虑使用更适合您的 kubernetes 设置的 php-fpm 进程管理器策略。
参考此PHP 手动配置了解更多信息。
编辑1
php-fpm 中的 ondemand 模式应该只在请求到达时产生工作进程。一旦请求被处理,工作进程应该默认终止。
在非 Kubernetes 环境中,运行php-fpm和一经请求模式并且没有传入请求应该导致只有主进程处于活动状态,就像您所经历的那样。
一些 Kubernetes 部署利用 Liveness 和 Readiness 探针来监控 Pod 的运行状况。即使没有传入请求,这些探针也可能定期触发工作进程生成。