重启 PHP-FPM(FastCGI Process Manager)是 PHP Web 应用运维中的高频操作,常用于部署新代码、更新配置、释放内存、恢复服务。但“重启”并非简单 kill 进程,其背后涉及进程模型、信号处理、平滑过渡、服务可用性四大核心维度。
一、PHP-FPM 的进程模型(重启的上下文)
PHP-FPM 采用Master-Worker 多进程架构:
php-fpm (master) ├── php-fpm: pool www (worker 1) ├── php-fpm: pool www (worker 2) └── ...- Master 进程:
- 监听配置文件(
php-fpm.conf); - 管理 Worker 进程生命周期;
- 不处理 HTTP 请求。
- 监听配置文件(
- Worker 进程:
- 处理实际的 FastCGI 请求;
- 请求结束后销毁所有变量(无内存泄漏);
- 每个 Worker 独立,互不影响。
✅重启的本质:重新加载 Master 进程,并优雅替换所有 Worker。
二、重启的三种方式:信号(Signal)驱动
PHP-FPM 通过Unix 信号接受外部指令,无需 kill -9。
1.reload(推荐:平滑重启)
kill-USR2$(cat/run/php-fpm.pid)# 或systemctl reload php-fpm- 行为:
- Master 重新读取
php-fpm.conf和pool/*.conf; - 启动新 Worker 进程;
- 等待旧 Worker 处理完当前请求后退出;
- 0 停机时间(Zero Downtime)。
- Master 重新读取
- 适用场景:
- 更新
php.ini配置; - 调整进程数(
pm.max_children); - 部署新代码(配合 OPcache 重置)。
- 更新
2.restart(硬重启)
kill-TERM$(cat/run/php-fpm.pid)# 或systemctl restart php-fpm- 行为:
- Master立即终止所有 Worker(无论是否在处理请求);
- 重新启动 Master + Worker;
- 可能导致请求 502(Bad Gateway)。
- 适用场景:
- PHP-FPM 崩溃无响应;
- 修改了 PHP 扩展(需重新加载 .so 文件)。
3.quit(优雅退出)
kill-QUIT$(cat/run/php-fpm.pid)- 行为:
- Master 停止接受新请求;
- 等待所有 Worker 完成当前任务后退出;
- 常用于服务下线。
✅信号总结:
信号 命令 行为 安全性 USR2reload平滑更新配置 ✅ 安全 TERMrestart强制重启 ⚠️ 可能丢请求 QUITquit优雅退出 ✅ 安全
三、重启时的 OPcache 行为(关键!)
reload:- 新 Worker 使用新的 OPcache;
- 旧 Worker 的 OPcache 仍保留,直到进程退出;
- 无需手动
opcache_reset()(因新进程自然加载新代码)。
restart:- 所有 OPcache 清空(因所有进程终止);
- 新请求触发重新编译(首次访问稍慢)。
⚠️陷阱:
若仅reload而未更新代码,新 Worker 仍会加载旧代码(因 OPcache 未失效)!
正确部署流程:gitpull# 更新代码systemctl reload php-fpm# 平滑重启
四、系统级集成:systemd 与日志
1.systemd 服务配置(/etc/systemd/system/php-fpm.service)
[Service] ExecReload=/bin/kill -USR2 $MAINPID KillMode=mixed # kill Master,Worker 自行退出systemctl reload php-fpm→ 自动发送USR2。
2.日志监控
- Master 日志(
/var/log/php-fpm.log):NOTICE: reloading: execvp("/usr/sbin/php-fpm", ...) - Worker 日志:
- 旧 Worker:
Graceful shutdown received - 新 Worker:
ready to handle connections
- 旧 Worker:
✅验证重启成功:
- 检查
php-fpm进程 PID 变化;- 观察日志
reloading记录。
五、高级场景:零停机部署的完整流程
部署脚本示例:
#!/bin/bash# 1. 拉取新代码gitpull origin main# 2. 清除 OPcache(可选,reload 已足够)# php -r "opcache_reset();"# 3. 平滑重启systemctl reload php-fpm# 4. 验证sleep2curl-f http://localhost/health-check||exit1六、常见错误与排查
| 问题 | 原因 | 解决 |
|---|---|---|
reload后代码未更新 | OPcache 仍缓存旧文件 | 确保部署后文件filemtime更新(git pull会自动更新) |
reload失败 | 配置文件语法错误 | 检查php-fpm -t验证配置 |
| 502 Bad Gateway | Worker 未及时启动 | 检查pm.start_servers是否足够 |
| 内存未释放 | reload不释放共享内存 | OPcache 共享内存需restart才清空(通常无需) |
七、总结:重启 PHP-FPM 的庖丁解牛要点
| 维度 | 核心理解 |
|---|---|
| 本质 | 通过信号控制 Master 进程,替换 Worker |
| 安全重启 | 用USR2(reload),非TERM(restart) |
| OPcache | reload后新进程自然加载新代码 |
| 部署最佳实践 | git pull+systemctl reload |
| 监控 | 查看日志reloading和Graceful shutdown |
| 陷阱 | 配置错误导致 reload 失败,旧进程持续运行 |
✅终极口诀:
“部署新码先 pull,reload 信号平滑渡;
不用 kill -9 粗暴,日志验证稳如初。”
作为中级 PHP 程序员,你必须掌握:
重启不是“重启”,而是“如何在不中断服务的前提下更新系统”——
这正是专业运维与业余操作的核心区别。