本文目录导读:

- 方法一:使用
SIGUSR2信号(最常用、最推荐) - 方法二:使用
reload命令(最便捷) - 方法三:使用
php-fpm的 CLI 控制(备选) - 高级技巧:平滑重启特定版本的 PHP(多版本共存时)
- 关键细节与注意事项
在 PHP 中实现平滑重启(Graceful Restart),主要是为了在更新代码或配置时,不中断现有请求,完成新旧进程的平稳过渡。它主要针对 PHP-FPM 模式,因为 mod_php 是随 Apache 进程启动的,无法独立控制。
PHP 本身没有像 Java 那样的“热部署”,平滑重启实际上是 FPM 的 Master 进程杀掉旧 Worker,并启动新 Worker 的过程,由于 Worker 进程处理完手头的请求后会自然退出,所以这被称为“平滑”。
以下是具体的实现方案和命令:
使用 SIGUSR2 信号(最常用、最推荐)
这是 Linux/Unix 系统下最标准的做法,FPM 的重启机制就是靠这个信号触发的。
-
找到 FPM 主进程(Master)的 PID:
# 方法1:查看 pid 文件(通常配置在 php-fpm.conf 或 www.conf 中) cat /usr/local/var/run/php-fpm.pid # 方法2:用 pgrep 搜索 pgrep -f "php-fpm: master"
-
发送平滑重启信号:
# 假设 PID 是 12345 kill -USR2 12345 # 或者更简洁: kill -USR2 $(cat /usr/local/var/run/php-fpm.pid)
执行效果:Master 进程会立即加载新的 php.ini 和 fpm.conf 配置,但旧的 Worker 进程会继续处理完手头的请求,处理完后自然死亡,新的 Worker 进程按新配置启动。
使用 reload 命令(最便捷)
如果你是通过 systemctl 或 service 管理 FPM,直接使用内置的重载命令即可,注意是 reload 而不是 restart:
# CentOS 7+ / RHEL 7+ / Ubuntu 16.04+ (systemd) systemctl reload php-fpm # 老版本 SysVinit 脚本 service php-fpm reload # 使用 init.d 脚本 /etc/init.d/php-fpm reload
注意:systemctl restart php-fpm 是强制重启(先 kill 所有进程再启动),会造成短暂的服务中断,不是平滑的。
使用 php-fpm 的 CLI 控制(备选)
如果你的环境没有集成 systemd,且管理脚本不完善,可以尝试直接调用二进制文件:
# 查看是否有 -g 参数(指定 pid 文件)和 -R 参数 php-fpm -R -g /usr/local/var/run/php-fpm.pid
解释:-R 表示快速启动,-g 指定 PID 文件,但这个方法更倾向于“重启”,不推荐用于线上平滑重启,最安全的还是上面的 SIGUSR2。
高级技巧:平滑重启特定版本的 PHP(多版本共存时)
如果你安装了 PHP 7.4 和 PHP 8.1 等,需要分别指定对应的配置文件:
# 找到对应的 conf 文件和 pid 文件路径 kill -USR2 $(cat /etc/php/8.1/fpm/php-fpm.pid)
关键细节与注意事项
-
配置生效范围:
reload只会重新加载php.ini、php-fpm.conf以及pool.d/下的配置(如www.conf)。- 注意:如果修改的是
php.ini中与扩展加载相关的配置(如extension=...),可能无法通过 reload 生效,因为扩展是在 Master 启动时加载的,通常需要完整重启,而修改memory_limit、upload_max_filesize等运行期配置,reload 即可生效。
- 注意:如果修改的是
-
慢日志与长连接:平滑重启时,如果有长连接请求(如 WebSocket 或长时间运行的任务)占据着旧 Worker,这些 Worker 不会立刻退出,如果这些请求卡死,旧的 Worker 会一直存在,此时可能需要配合超时时间设置(
request_terminate_timeout),或者在流量低谷时段进行 reload。 -
如何确认重启成功? 执行 reload 后,查看进程列表:
ps aux | grep php-fpm
你会看到
master process的启动时间变成了刚刚,但旧的pool www进程的启动时间还是旧的,等旧的 worker 处理完请求后,ps会看到所有 worker 的启动时间都变成了新的。 -
权限问题:执行
kill需要操作者拥有足够权限(通常是root或php-fpm用户)。
在 PHP-FPM 环境下,systemctl reload php-fpm 或 kill -USR2 <master_pid> 就是最标准的平滑重启方式。
千万避免使用 systemctl restart 或 killall php-fpm,除非你接受短时间的 502 错误(连接被关闭)。