旧 master 未被 quit 终止前仍驻留内存、持有端口并可响应信号,故能通过 hup 重启旧版 worker 并 quit 新 master 实现无中断回滚。

当 Nginx 平滑升级失败时,回滚不是重启服务或手动杀进程,而是利用旧 Master 进程仍在运行这一关键状态,通过信号控制快速恢复旧版本服务能力。核心在于:旧 Master 没有被 kill -QUIT 终止前,它始终保有“重新接管流量”的能力。
旧 Master 为何能回滚?
平滑升级过程中,旧 Master 进程不会立即退出。它在收到 USR2 后派生新 Master,自身继续存活;收到 WINCH 后仅逐步关停自己的 worker,但自身仍驻留内存、持有监听端口(由内核维持)、并可响应信号。只要它没收到 QUIT,就仍是整个旧版服务的“指挥中枢”。
回滚的两个必要动作
- 向旧 Master 发送 HUP 信号:触发旧 Master 用当前加载的配置(即原配置)重新 fork 一批新的 worker 进程。这些新 worker 与旧版二进制完全兼容,能立刻开始接收新请求。
- 向新 Master 发送 QUIT 信号:让新 Master 主动退出,并逐个等待其下属 worker 处理完剩余请求后关闭。这避免了新旧 worker 同时争抢连接或产生状态混乱。
回滚生效的关键前提
回滚能否成功,取决于三个硬性条件是否满足:
- 旧版 nginx 二进制文件未被覆盖或已备份(如 nginx.old),否则 HUP 无法启动兼容 worker;
- 旧 Master 进程 PID 仍可获取(通常来自 /var/run/nginx.pid 或 /usr/local/nginx/logs/nginx.pid);
- 尚未执行过 kill -QUIT —— 一旦旧 Master 退出,就彻底失去回滚入口。
回滚后的状态还原
完成上述操作后,系统将回到升级前的稳定态:只有旧版 Master 和它新拉起的 worker 在运行,所有新请求由旧版处理;新 Master 及其 worker 全部退出;nginx.pid 恢复指向旧 Master,.oldbin 文件自动失效或可手动清理。整个过程不中断连接,也不丢请求。










