PHP-FPM进程如何热重启worker进程?
PHP-FPM 不能“点名重启某一个子进程”,但可以用信号、pm 策略和 reload 机制,让子进程被安全回收并重建。
1. PHP-FPM 进程模型
1.1 角色划分
Master 进程
- 读取配置
- 监听 socket/端口
- 管理 Worker(子进程)
Worker / Child 进程
- 实际执行 PHP 请求
- 按 pm 策略自动增减
- 崩溃后由 Master 拉起
1.2 master-worker关系示意
graph TD
M[php-fpm master]
C1[worker 1]
C2[worker 2]
C3[worker N]
M --> C1
M --> C2
M --> C3
关键点:所有“重启子进程”的动作,本质都是 Master 在做调度。
2. 如何优雅重启worker进程
2.1 平滑重载(最推荐)
1 | kill -USR2 <php-fpm-master-pid> |
效果
- Master 重新加载配置
- 旧子进程:处理完当前请求后退出
- 新子进程:逐步拉起
- 对线上请求影响最小(几乎无感)
👉 这是 生产环境首选
2.2 使用 systemctl reload
1 | systemctl reload php-fpm |
等价于 USR2,更规范。
3. 只重启子进程的实际可行方案
3.1 杀掉 Worker,让 Master 自动重建
不建议
3.1.1 找到 Worker PID
1 | ps -ef | grep php-fpm | grep pool |
示例输出:
www 12345 1000 php-fpm: pool www
www 12346 1000 php-fpm: pool www
3.1.2 kill 某个子进程
1 | kill -TERM 12345 |
结果
- 这个 worker 退出
- Master 立刻拉起一个新的 worker
- 其他 worker 不受影响
这是最接近“重启指定子进程”的方式
3.2 快速回收全部子进程(不中断 Master)
1 | kill -WINCH <master-pid> |
效果
- 所有 worker 优雅退出
- Master 仍在
- 随后根据 pm 策略重新 fork
⚠️ 短时间并发能力会下降,不适合流量高峰。
4. 信号速查表
| 信号 | 作用 | 是否推荐 |
|---|---|---|
USR2 |
平滑 reload(重建子进程) | ⭐⭐⭐⭐⭐ |
TERM |
杀某个 worker | ⭐⭐⭐⭐ |
WINCH |
停掉全部 worker | ⭐⭐ |
QUIT |
优雅关闭整个 FPM | ⚠️ |
KILL |
强杀 | ❌ 生产禁用 |
5. 通过 pm 策略“自动重启异常子进程”(根治方案)
5.1 推荐配置(生产)
1 | pm = dynamic |
5.2 原理
每个 worker 执行 1000 次请求后 自动退出
Master 自动拉起新 worker
无需人工干预
非常适合:
- 内存泄漏
- 扩展不稳定
- 第三方 SDK 有问题
6. 不推荐但你可能见过的“野路子”
6.1 重启 php-fpm 服务
1 | systemctl restart php-fpm |
❌ 问题:
- 所有请求中断
- socket 断开
- 对 Nginx 不友好
只适合 配置错误 / FPM 卡死
7. 生产级操作建议
7.1 正确操作顺序
单 worker 异常
kill -TERM <worker-pid>
批量内存上涨(解决内存泄露问题)
- 调低
pm.max_requests
- 调低
配置调整
systemctl reload php-fpm
整体异常
- 才考虑 restart