一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Nginx 中 PHP-FPM 如何在升级版本时保障业务零中断

时间:2026-08-24 11:50:48 编辑:袖梨 来源:一聚教程网

PHP-FPM原生支持平滑重启与优雅切换,配合Nginx的fastcgi_pass动态转发可实现零中断升级;关键在于新旧实例并行、Nginx层流量切换、进程自然退出及完备回滚。

PHP-FPM 本身不支持像 Nginx 那样的二进制热升级(USR2/WINCH 流程),但它原生支持平滑重启与进程优雅切换,配合 Nginx 的 fastcgi_pass 转发机制,完全可实现 PHP 版本升级过程中的业务零中断。关键不是“同时运行两个 PHP-FPM”,而是让新旧 PHP-FPM 实例在 Nginx 层面完成无缝流量切换,并确保存量请求处理完毕。

确认 PHP-FPM 运行模式与配置兼容性

PHP-FPM 必须以 socket 方式(unix:/var/run/php-fpm.sock)或 TCP 端口(127.0.0.1:9000)独立监听,不能嵌入 Nginx 进程;且 Nginx 的 fastcgi_pass 指向必须可动态调整。检查当前配置:

  1. 运行 ps aux | grep php-fpm,确认主进程存在且 worker 数量合理
  2. 查看 php-fpm.confpiderror_loglisten 路径是否明确,避免升级后路径冲突
  3. 确认 pm = dynamicondemand,并设置 pm.graceful_timeout = 60(保障长连接有足够时间退出)

双实例并行:先启新 PHP-FPM,再切流

核心策略是部署新版 PHP-FPM 实例,与旧版共存,通过修改 Nginx upstream 或重载配置完成灰度切换。操作步骤如下:

  1. 编译安装新 PHP 版本(如 8.3.12),指定独立前缀(如 --prefix=/usr/local/php83),避免覆盖旧版
  2. 复制并修改新 PHP-FPM 配置(如 /usr/local/php83/etc/php-fpm.d/www.conf),将 listen 改为新 socket 路径(如 /var/run/php83.sock)或新端口(如 9001
  3. 启动新实例:/usr/local/php83/sbin/php-fpm -y /usr/local/php83/etc/php-fpm.conf,验证其监听状态(ss -ltp | grep 9001
  4. 临时更新 Nginx server 块中的 fastcgi_pass,指向新地址(如 fastcgi_pass unix:/var/run/php83.sock;),执行 nginx -t && nginx -s reload

分阶段切换 + 监控验证

切换不是一蹴而就,需观察稳定性后再彻底下线旧版:

  1. 切流后立即检查:Nginx 错误日志(tail -f error.log)、PHP-FPM 新旧日志中是否有 WARNINGSEGV
  2. 用 curl 或浏览器访问典型 PHP 页面(如 phpinfo()),确认响应头 X-Powered-By 显示新版 PHP
  3. 观察旧 PHP-FPM worker 是否自然减少:运行 sudo /usr/local/php74/sbin/php-fpm -t 后,执行 kill -USR2 $(cat /usr/local/php74/var/run/php-fpm.pid) 触发优雅重启(仅当需回收旧资源时)
  4. 确认所有旧 worker 已退出(ps aux | grep php74 | grep -v grep 无输出)后,再停止旧主进程:kill -QUIT $(cat /usr/local/php74/var/run/php-fpm.pid)

回滚方案必须就绪

零中断的前提是失败可秒退:

  1. 切换前备份旧 PHP-FPM 配置、二进制及 Nginx 对应的 fastcgi_pass 行
  2. 准备一键回切脚本:还原 Nginx 配置 + nginx -s reload + 若旧实例已停,则 /usr/local/php74/sbin/php-fpm -y /usr/local/php74/etc/php-fpm.conf
  3. 注意 session 兼容性:PHP 8.2+ 默认禁用 session.serialize_handler=php_serialize,若旧版用 php 格式序列化,升级前需显式配置保持一致,否则登录态丢失

热门栏目