平滑升级nginx二进制文件需严格按步骤操作:先确认旧编译参数、检查systemd托管、记录pid位置;再用原参数编译新版本,仅cp覆盖sbin/nginx并验证语法;最后依次发送usr2、winch、quit信号完成无缝切换,全程不断连,支持回滚。

平滑重载配置(nginx -s reload)和**平滑升级二进制文件**是两件事:前者只重新加载配置、重启 worker 进程,不换程序;后者才是替换 nginx 可执行文件并切换到新版主进程,全程不断连。
确认旧版编译参数,避免升级卡死
跳过这步,90% 的升级会在 USR2 阶段失败——新 master 启动不了,因为模块缺失或路径错:
- 运行
/usr/local/nginx/sbin/nginx -V(大写 V),抄下完整--prefix、--conf-path、所有--with-xxx-module(如--with-http_ssl_module) - 检查是否由 systemd 托管:
ps aux | grep nginx,若看到systemd字样,后续信号必须用systemctl kill --signal=USR2 nginx,不能直接kill - 记下 PID 文件位置(通常是
/usr/local/nginx/logs/nginx.pid),所有信号都靠它定位主进程
编译新二进制并安全覆盖
严禁 make install,否则会误删 conf/、html/ 等目录:
- 解压新源码,进入目录,用旧参数执行
./configure(例如:./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module) - 执行
make(只编译,生成新二进制在objs/nginx) - 备份旧文件:
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak - 复制新文件:
cp objs/nginx /usr/local/nginx/sbin/nginx(若提示Text file busy,属正常,WINCH 后再覆盖也来得及) - 验证语法:
/usr/local/nginx/sbin/nginx -t必须返回success
按顺序发信号完成无缝切换
三个信号有严格依赖,顺序错或 PID 错会导致降级或无法回滚:
- 发
USR2:kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)→ 启动新 master,此时ps aux | grep nginx显示两组进程(旧 master + 新 master,各自 worker) - 发
WINCH到旧 master:kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid.oldbin)→ 旧 worker 开始优雅退出(不接新请求,但继续处理长连接、WebSocket、大文件下载等已有连接) - 等旧 worker 全退出后,发
QUIT到旧 master:kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)→ 关闭旧 master,清理nginx.pid.oldbin
验证与回滚准备
升级中随时可回退,关键在备份和信号可控:
- 验证:用
curl -I或访问业务接口,确认响应头含新版本号;也可查ps aux | grep nginx是否只剩新 master 和 worker - 回滚操作:若新版本异常,立即
kill -QUIT新 master,再把备份的nginx.bak复制回去,kill -HUP旧 master 即可恢复 - 注意:整个过程不中断任何已建立连接,HTTP/2 流、WebSocket、上传中请求均不受影响











