nginx零停机热升级通过usr2/winch/quit三步信号实现:先启新master与worker并存,再优雅关闭旧worker,最后终止旧master;须确保编译参数一致、配置测试通过、回滚路径完备。

不用停服务,靠信号机制就能完成主程序升级。核心是让新旧两个 master 进程并存,由新 master 启动新 worker 接管新请求,旧 worker 处理完手头任务再退出。
确认当前版本和编译参数
先查清楚正在运行的 Nginx 是怎么编译出来的,这决定了新版本必须用完全一致的 configure 参数:
- 执行 /usr/local/nginx/sbin/nginx -V(注意大写 V),看输出里的 configure arguments: 行
- 如果参数为空或缺失模块(比如没加
--with-http_ssl_module),新编译时必须补全,否则启动会失败 - 特别留意第三方依赖路径,例如
--with-openssl=/path/to/openssl,路径必须真实存在且版本兼容
编译新版本但不安装
下载新源码包后,只编译出二进制文件,不执行 make install,避免覆盖配置:
- 进入解压目录,运行 ./configure 加上刚才抄到的全部参数
- 运行 make(不是
make install) - 编译成功后,新二进制在 objs/nginx,把它拷贝到安全位置,比如:
cp objs/nginx /usr/local/nginx/sbin/nginx-1.30.4
替换并触发平滑切换
备份旧程序后,用信号分三步完成切换:
- 先备份: cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
- 替换软链接或重命名: mv /usr/local/nginx/sbin/nginx-1.30.4 /usr/local/nginx/sbin/nginx
- 发 USR2 信号启动新 master:kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)
- 发 WINCH 信号让旧 worker 逐步退出:kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid)
- 等旧 worker 全部消失(ps aux | grep nginx 只剩一组进程),再发 QUIT 关旧 master:kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid)
验证与回滚准备
升级不是结束,验证和兜底同样重要:
- 检查新进程是否正常:nginx -V 看版本号,nginx -t 确认配置可用
- 观察日志:tail -f /usr/local/nginx/logs/error.log 看有无报错
- 访问业务接口,确认响应头中 Server: nginx/1.30.4 已生效
- 保留 nginx.bak 文件,万一异常,立刻换回并 kill -HUP 重新加载即可恢复











