平滑升级Nginx是在不中断服务前提下完成新旧版本热切换,核心依赖master-worker模型与信号机制;需先备份、验证兼容性,再通过USR2/WINCH/QUIT信号分步替换进程,回滚同理。

平滑升级 Nginx 指的是在不中断服务、不丢失请求的前提下完成新版本二进制文件的替换和工作进程的热切换;回滚则是当新版本出现兼容性或稳定性问题时,快速恢复到旧版运行状态。核心在于利用 Nginx 的 master-worker 进程模型 和 信号控制机制,而非简单重启。
一、升级前的必要准备
确保升级过程可控、可逆,必须提前完成以下动作:
-
确认当前版本与配置路径:执行
nginx -v和nginx -t -c /etc/nginx/nginx.conf,记录版本号、编译参数(nginx -V)、配置文件位置及加载模块列表; -
备份旧二进制与配置:将原
/usr/sbin/nginx复制为/usr/sbin/nginx.old,同时备份整个/etc/nginx/目录; -
编译新版本(如需自定义模块):使用与旧版一致的 configure 参数(尤其是
--prefix、--modules-path、--with-xxx),避免因模块缺失导致启动失败; -
验证新二进制兼容性:用
./objs/nginx -t -c /etc/nginx/nginx.conf测试配置语法,再用./objs/nginx -V核对模块是否齐全。
二、执行平滑升级(无中断)
关键步骤是用新二进制替换旧文件后,通过信号通知 master 进程优雅地启用新版 worker:
- 停止旧版 nginx 的自动管理(如 systemd):运行
systemctl stop nginx或直接 kill master 进程(仅当未托管时); - 将新编译好的
./objs/nginx复制到/usr/sbin/nginx,覆盖原文件; - 启动旧 master 进程(若已停止):
/usr/sbin/nginx,此时仍运行旧版 worker; - 向旧 master 发送
USR2信号:kill -USR2 $(cat /var/run/nginx.pid),Nginx 启动新 master 并派生新 worker,新旧版本并存; - 向旧 master 发送
WINCH信号:kill -WINCH $(cat /var/run/nginx.pid),旧 worker 逐步退出(处理完当前连接后关闭); - 确认旧 worker 全部退出后,向旧 master 发送
QUIT信号,彻底终止旧 master;新 master 接管全部 PID 文件与监听端口。
三、快速回滚到旧版本
若升级后发现异常(如 502、CPU 飙升、模块失效),立即回滚无需重新编译:
- 将备份的
/usr/sbin/nginx.old复制回/usr/sbin/nginx; - 向当前新 master 进程发送
USR2信号,启动旧版 master(注意此时会有两个 master 并存); - 向新 master 发送
WINCH,使其 worker 优雅退出; - 向新 master 发送
QUIT,终止其进程; - 检查
ps aux | grep nginx和nginx -v确认已回归旧版,服务持续可用。
四、验证与收尾要点
升级/回滚完成后必须验证实际效果,不能只看进程是否存在:
- 用
curl -I http://localhost或真实业务请求测试响应头、状态码、静态资源与动态接口是否正常; - 检查错误日志:
tail -f /var/log/nginx/error.log,关注是否有模块加载失败、配置项弃用等 warning; - 确认 PID 文件指向正确 master:
cat /var/run/nginx.pid对应的进程是否为当前运行版本; - 如使用 systemd,更新
/usr/lib/systemd/system/nginx.service中的ExecReload,确保nginx -s reload行为与新版兼容。
整个过程不依赖外部工具,完全基于 Nginx 原生命令与信号,只要操作顺序准确、备份完整,就能实现真正的零停机升级与秒级回滚。










