PHP-FPM(PHP FastCGI Process Manager)是 PHP 官方提供的 FastCGI 进程管理器,主要负责接收 Web 服务器转发过来的 PHP 请求,并调度 PHP worker 进程执行脚本。它常与 Nginx、Apache 等 Web 服务器配合使用,是 PHP 网站高并发部署中的核心组件。

理解 PHP-FPM 的进程模型,有助于排查 PHP 网站中的慢请求、502 错误、进程耗尽、内存过高和并发不足等问题。

一、PHP-FPM 在请求链路中的位置

一个常见的 PHP 网站请求链路如下:

用户浏览器 → Nginx/Apache → PHP-FPM → PHP Worker → 执行 PHP 脚本 → 返回结果

Web 服务器负责接收 HTTP 请求和处理静态资源;PHP-FPM 负责管理 PHP 进程池;worker 子进程负责真正执行 PHP 代码。

Nginx 本身不会直接执行 PHP 文件,它通常通过 FastCGI 协议把请求交给 PHP-FPM。

二、PHP-FPM 的主进程和子进程

1. Master 主进程

PHP-FPM 启动后会先创建 master 主进程。主进程不直接处理业务请求,它主要负责管理 worker 子进程。

主进程职责包括:

  1. 读取 PHP-FPM 配置文件。
  2. 创建和回收 worker 子进程。
  3. 监听进程信号,例如 reload、stop、restart。
  4. 管理不同 pool 的运行状态。
  5. 记录日志和处理异常退出。

2. Worker 子进程

worker 子进程负责处理实际 PHP 请求。每个请求会被分配给一个空闲 worker,执行完成后 worker 再继续等待下一个请求。

worker 数量过少,会导致请求排队;数量过多,则可能导致内存占用过高,甚至拖垮服务器。

三、PHP-FPM 进程池是什么

PHP-FPM 支持配置多个 pool。每个 pool 可以有独立的用户、监听地址、进程数量、日志、慢请求配置和 PHP 参数。

常见用途包括:

  1. 不同站点使用不同 pool 隔离。
  2. 前台和后台使用不同 pool。
  3. 高风险业务和核心业务分开运行。
  4. 不同项目使用不同 PHP 配置。

使用 pool 可以提升隔离性,避免某个站点或模块异常影响所有 PHP 请求。

四、常见进程管理模式

PHP-FPM 的 pm 参数决定 worker 进程如何管理。

模式 特点 适用场景
static 固定数量 worker 流量稳定、资源充足
dynamic 动态增减 worker 大多数 Web 网站
ondemand 有请求时才创建 worker 低访问量或节省资源场景

static

static 模式会始终保持固定数量的 worker。优点是性能稳定,缺点是空闲时也占用内存。

dynamic

dynamic 模式会根据请求量在最小和最大范围内调整 worker 数量,是最常用的模式。

常见参数包括:

pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20

ondemand

ondemand 模式在有请求时才启动 worker,空闲一段时间后自动退出。它节省资源,但首次请求可能稍慢。

五、关键配置参数说明

1. pm.max_children

pm.max_children 是最大 worker 数量。它决定 PHP-FPM 同时能处理多少个 PHP 请求。

配置过小会导致请求排队;配置过大可能导致内存耗尽。可以按单个 PHP 进程平均内存估算:

可用于 PHP 的内存 / 单个 worker 平均内存 = max_children 参考值

2. request_terminate_timeout

用于限制单个请求最长执行时间。如果某些 PHP 请求卡住,可以通过它避免 worker 长时间被占用。

3. slowlog

慢日志用于定位执行时间过长的 PHP 脚本。开启慢日志后,可以看到慢请求卡在哪些函数或文件中。

request_slowlog_timeout = 3s
slowlog = /var/log/php-fpm/slow.log

4. pm.max_requests

一个 worker 处理指定数量请求后会自动重启。它可以缓解 PHP 应用中的内存泄漏问题。

六、常见问题与排查思路

1. 502 Bad Gateway

常见原因包括:

  1. PHP-FPM 没有启动。
  2. Nginx 配置的 socket 或端口错误。
  3. worker 全部被占满。
  4. PHP 脚本执行超时。
  5. PHP-FPM 进程崩溃或内存不足。

排查时应查看 Nginx error log、PHP-FPM error log 和系统内存状态。

2. 请求变慢

如果 PHP 请求变慢,可以检查:

  1. 是否有慢 SQL。
  2. 是否有远程接口阻塞。
  3. worker 是否被耗尽。
  4. 是否有大量文件 IO。
  5. 是否需要开启慢日志定位。

3. 进程数量过高

进程数量过高不一定是好事。需要结合内存、CPU、请求耗时和队列情况判断。如果单个 worker 内存很大,过多 worker 会导致系统频繁 swap。

七、PHP-FPM 优化建议

  1. 根据服务器内存合理设置 pm.max_children
  2. 为高流量站点使用 dynamicstatic 模式。
  3. 开启 slowlog 定位慢请求。
  4. 使用 pm.max_requests 缓解内存泄漏。
  5. 将不同站点或业务拆分到不同 pool。
  6. 配合 OPcache 提升 PHP 执行效率。
  7. 监控 active processes、idle processes、listen queue 等指标。

总结

PHP-FPM 是 PHP 网站运行中的关键进程管理器。master 进程负责管理,worker 子进程负责执行 PHP 请求,pool 用于隔离不同站点或业务。

优化 PHP-FPM 不是简单地把进程数调大,而是要结合服务器内存、请求耗时、并发量、慢日志和业务特点综合配置。理解它的进程模型和关键参数,才能更有效地排查性能问题和提升 PHP 网站稳定性。