零停机升级靠master进程调度实现,不关端口、不断连接、不丢请求;分三步:usr2启新master、winch停旧worker、quit退旧master;需二进制兼容与回滚验证。

靠 Master 进程实现零停机升级,核心不是“替换就完事”,而是利用它对 Worker 的调度权和信号响应能力,在新旧版本间做进程交接。整个过程不关闭监听端口、不中断长连接、不丢请求。
理解 Master 的双重角色
Master 不处理请求,但掌控全局:它持有所有监听 socket(如 80/443),并负责 fork 和管理 Worker。升级时,它要完成两件事:
- 启动新 Master,并把监听 socket “移交”过去(实际是继承 fd,非复制)
- 控制旧 Worker 何时停止接收新连接、何时退出当前请求
这种分离设计让新旧版本可以共存——新 Master 带着新 Worker 接管新流量,旧 Worker 继续服务未完成的请求。
三步信号流程必须严格顺序执行
信号不是发给任意进程,而是精准作用于特定 Master,顺序错一步就可能中断服务:
- USR2 → 当前 Master:触发启动新 Master 进程,后者读取新二进制和配置,生成自己的 Worker;此时系统中存在两个 Master(旧 PID 和新 PID.oldbin)和两组 Worker
- WINCH → 旧 Master:通知它逐个关闭所辖 Worker;旧 Worker 进入 graceful shutdown 状态——不再 accept 新连接,但继续处理已建立的连接(包括 keep-alive、上传中、慢查询等)
- QUIT → 旧 Master:等所有旧 Worker 退出后,旧 Master 自行终止;此时只剩新 Master + 新 Worker,升级完成
注意:旧 Master 的 PID 文件会自动变为 nginx.pid.oldbin,这是识别和发送 WINCH/QUIT 的关键依据。
二进制替换与兼容性是前提
信号再准,也救不了不兼容的二进制:
- 新版本编译时,必须复用旧版本的 configure 参数(用
nginx -V查),尤其涉及模块(如 --with-http_ssl_module)、OpenSSL 版本、PCRE 路径等 - 新二进制文件不能直接覆盖,推荐先备份旧版:
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx-1.22.1,再拷入新版并软链或重命名 - 升级前务必用新二进制测试配置:
/usr/local/nginx/sbin/nginx-1.24.0 -t -c /usr/local/nginx/conf/nginx.conf
回滚方案必须提前验证
生产环境出问题,不能等重启——回滚要和升级一样快:
- 若发现新版本异常,立即向 新 Master 发送 QUIT(让它退出),再向 旧 Master 发送 HUP(重启它的 Worker)
- 确保旧二进制仍可执行、旧配置未被修改、日志路径未变更
- 建议将整个升级+回滚流程写成脚本,并在预发环境跑通至少一次











