PHP平滑重启怎么做

wen PHP项目 3

本文目录导读:

PHP平滑重启怎么做

  1. 方法一:使用 SIGUSR2 信号(最常用、最推荐)
  2. 方法二:使用 reload 命令(最便捷)
  3. 方法三:使用 php-fpm 的 CLI 控制(备选)
  4. 高级技巧:平滑重启特定版本的 PHP(多版本共存时)
  5. 关键细节与注意事项

在 PHP 中实现平滑重启(Graceful Restart),主要是为了在更新代码或配置时,不中断现有请求,完成新旧进程的平稳过渡。它主要针对 PHP-FPM 模式,因为 mod_php 是随 Apache 进程启动的,无法独立控制。

PHP 本身没有像 Java 那样的“热部署”,平滑重启实际上是 FPM 的 Master 进程杀掉旧 Worker,并启动新 Worker 的过程,由于 Worker 进程处理完手头的请求后会自然退出,所以这被称为“平滑”。

以下是具体的实现方案和命令:


使用 SIGUSR2 信号(最常用、最推荐)

这是 Linux/Unix 系统下最标准的做法,FPM 的重启机制就是靠这个信号触发的。

  1. 找到 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"
  2. 发送平滑重启信号

    # 假设 PID 是 12345
    kill -USR2 12345
    # 或者更简洁:
    kill -USR2 $(cat /usr/local/var/run/php-fpm.pid)

执行效果:Master 进程会立即加载新的 php.inifpm.conf 配置,但旧的 Worker 进程会继续处理完手头的请求,处理完后自然死亡,新的 Worker 进程按新配置启动。


使用 reload 命令(最便捷)

如果你是通过 systemctlservice 管理 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)

关键细节与注意事项

  1. 配置生效范围reload 只会重新加载 php.iniphp-fpm.conf 以及 pool.d/ 下的配置(如 www.conf)。

    • 注意:如果修改的是 php.ini 中与扩展加载相关的配置(如 extension=...),可能无法通过 reload 生效,因为扩展是在 Master 启动时加载的,通常需要完整重启,而修改 memory_limitupload_max_filesize 等运行期配置,reload 即可生效。
  2. 慢日志与长连接:平滑重启时,如果有长连接请求(如 WebSocket 或长时间运行的任务)占据着旧 Worker,这些 Worker 不会立刻退出,如果这些请求卡死,旧的 Worker 会一直存在,此时可能需要配合超时时间设置(request_terminate_timeout),或者在流量低谷时段进行 reload。

  3. 如何确认重启成功? 执行 reload 后,查看进程列表:

    ps aux | grep php-fpm

    你会看到 master process 的启动时间变成了刚刚,但旧的 pool www 进程的启动时间还是旧的,等旧的 worker 处理完请求后,ps 会看到所有 worker 的启动时间都变成了新的。

  4. 权限问题:执行 kill 需要操作者拥有足够权限(通常是 rootphp-fpm 用户)。


在 PHP-FPM 环境下,systemctl reload php-fpmkill -USR2 <master_pid> 就是最标准的平滑重启方式。

千万避免使用 systemctl restartkillall php-fpm,除非你接受短时间的 502 错误(连接被关闭)。

抱歉,评论功能暂时关闭!