nginx 中 php-fpm 的平滑切换本质是不重启 nginx、不改配置,仅替换后端服务:一、复用同一 unix socket 路径(推荐),确保权限一致后启新停旧;二、复用同一 tcp 端口,需避免冲突;三、多版本共存时修改 fastcgi_pass 并 reload 实现准平滑切换。

Nginx 本身不处理 PHP,它通过 FastCGI 协议把 .php 请求转发给 PHP-FPM 进程管理器。所以“Nginx 中 PHP-FPM 的平滑切换”,本质是让 Nginx 在不中断请求的前提下,把流量从旧版 PHP-FPM 切到新版 PHP-FPM——这和 Nginx 自身的平滑升级不同,关键在于不重启 Nginx、不改监听端口或 socket 路径、只替换后端服务。
下面分三类常见场景说明怎么做,核心目标都是:用户访问无感知、正在处理的请求不丢、新请求自动走新版本。
H3>一、用 Unix Socket 且新版 PHP-FPM 监听同一路径(推荐)
这是最稳妥的平滑切换方式,前提是新版 PHP-FPM 配置中 listen = /var/run/php/php8.4-fpm.sock 和旧版完全一致(包括权限、用户、group)。
- 确保新版 PHP-FPM 已安装并配置好,但先不要启动
- 编辑新版 pool 配置(如
/etc/php/8.4/fpm/pool.d/www.conf),确认:-
listen = /var/run/php/php8.4-fpm.sock(与旧版 sock 文件路径相同) -
listen.owner和listen.group与旧版一致(通常是www-data或nginx) -
user/group与旧版一致(避免文件读取权限问题)
-
- 启动新版 PHP-FPM:
systemctl start php8.4-fpm - 等待它成功监听 socket(可用
ls -l /var/run/php/php8.4-fpm.sock检查) -
停止旧版 PHP-FPM:
systemctl stop php7.4-fpm(或对应旧服务名) - 此时 Nginx 仍连着同一个 socket 路径,自动开始将新请求发给新版进程
- 旧连接若还在处理,会继续由旧 worker 完成(但旧服务已停,所以实际依赖的是:旧 worker 在 stop 前已承接的请求是否能自然结束;只要没强制 kill,不会中断)
✅ 优势:零 Nginx 配置变更、零 reload、无连接中断风险
⚠️ 注意:必须确保 socket 路径、权限、SELinux 上下文(如启用)完全一致,否则 Nginx 会报 connect() to unix:/... failed (13: Permission denied)
H3>二、用 TCP 端口(如 9000)且新版监听同一端口
适合开发环境或端口资源宽松的场景,原理类似 socket,但需端口复用。
- 新版 PHP-FPM 配置中设
listen = 127.0.0.1:9000,并确保listen.allowed_clients = 127.0.0.1 - 启动新版:
systemctl start php8.4-fpm - 确认端口已被占用:
ss -tlnp | grep ':9000' - 停止旧版:
systemctl stop php7.4-fpm - Nginx
fastcgi_pass 127.0.0.1:9000;不变,后续请求自动路由至新版
✅ 简单直接
⚠️ 风险:若两个版本同时运行,会端口冲突;务必先停旧、再启新,或用 systemctl restart php8.4-fpm 替代 start(它会自动停旧同名实例,但仅限同一服务单元)
H3>三、多版本共存 + Nginx 动态切换(需 reload,但可控制窗口)
当不能复用 socket 或端口(例如旧版必须长期保留),可通过修改 Nginx server 块中的 fastcgi_pass 并 reload 实现“准平滑”切换。
- 先为新版 PHP-FPM 配独立 socket(如
/var/run/php/php8.4-fpm.sock)并启动 - 备份原站点配置:
cp /etc/nginx/sites-enabled/my-site /etc/nginx/sites-enabled/my-site.bak - 修改配置,把
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;换成fastcgi_pass unix:/var/run/php/php8.4-fpm.sock; - 检查语法:
nginx -t -
执行 reload:
nginx -s reload或systemctl reload nginx - 此时:
- 已建立的长连接(如 WebSocket、Keep-Alive 未关闭的请求)仍走旧 PHP-FPM,直到连接自然关闭
- 所有新连接和新请求全部走新版
- reload 本身耗时毫秒级,用户几乎无感;只要旧 PHP-FPM 进程还在,存量请求就不会中断
✅ 灵活、可控、适合生产灰度
⚠️ 注意:reload 不等于 restart,不会 kill worker,所以不是真正“中断”,只是新连接路由变更
不复杂但容易忽略
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











