PHP-FPM原生支持平滑重启与优雅切换,配合Nginx的fastcgi_pass动态转发可实现零中断升级;关键在于新旧实例并行、Nginx层流量切换、进程自然退出及完备回滚。
PHP-FPM 本身不支持像 Nginx 那样的二进制热升级(USR2/WINCH 流程),但它原生支持平滑重启与进程优雅切换,配合 Nginx 的 fastcgi_pass 转发机制,完全可实现 PHP 版本升级过程中的业务零中断。关键不是“同时运行两个 PHP-FPM”,而是让新旧 PHP-FPM 实例在 Nginx 层面完成无缝流量切换,并确保存量请求处理完毕。
PHP-FPM 必须以 socket 方式(unix:/var/run/php-fpm.sock)或 TCP 端口(127.0.0.1:9000)独立监听,不能嵌入 Nginx 进程;且 Nginx 的 fastcgi_pass 指向必须可动态调整。检查当前配置:
ps aux | grep php-fpm,确认主进程存在且 worker 数量合理php-fpm.conf 中 pid、error_log、listen 路径是否明确,避免升级后路径冲突pm = dynamic 或 ondemand,并设置 pm.graceful_timeout = 60(保障长连接有足够时间退出)核心策略是部署新版 PHP-FPM 实例,与旧版共存,通过修改 Nginx upstream 或重载配置完成灰度切换。操作步骤如下:
--prefix=/usr/local/php83),避免覆盖旧版/usr/local/php83/etc/php-fpm.d/www.conf),将 listen 改为新 socket 路径(如 /var/run/php83.sock)或新端口(如 9001)/usr/local/php83/sbin/php-fpm -y /usr/local/php83/etc/php-fpm.conf,验证其监听状态(ss -ltp | grep 9001)fastcgi_pass,指向新地址(如 fastcgi_pass unix:/var/run/php83.sock;),执行 nginx -t && nginx -s reload
切换不是一蹴而就,需观察稳定性后再彻底下线旧版:
tail -f error.log)、PHP-FPM 新旧日志中是否有 WARNING 或 SEGV
phpinfo()),确认响应头 X-Powered-By 显示新版 PHPsudo /usr/local/php74/sbin/php-fpm -t 后,执行 kill -USR2 $(cat /usr/local/php74/var/run/php-fpm.pid) 触发优雅重启(仅当需回收旧资源时)ps aux | grep php74 | grep -v grep 无输出)后,再停止旧主进程:kill -QUIT $(cat /usr/local/php74/var/run/php-fpm.pid)
零中断的前提是失败可秒退:
nginx -s reload + 若旧实例已停,则 /usr/local/php74/sbin/php-fpm -y /usr/local/php74/etc/php-fpm.conf
session.serialize_handler=php_serialize,若旧版用 php 格式序列化,升级前需显式配置保持一致,否则登录态丢失