Nginx 平滑升级与回滚超详细指南

Nginx 平滑升级与回滚

本文档整理了用源码编译后,无中断地把 Nginx 二进制替换为新版本(平滑升级)以及在出现问题时回滚到旧版本的常用流程、信号说明与注意事项。适用于用源码安装并把 nginx 可执行文件放在 /usr/local/nginx/sbin/nginx 情况下。

重要提醒:在升级前务必备份当前二进制和配置信息,确认新版本在测试环境通过(尤其是模块/依赖是否一致)。在生产上操作前先在灰度环境演练一次流程。

主要信号(简要)

  • USR2 --- 让旧 master 启动新 master(使用新二进制),并保留旧 master(旧 master 的 pid 文件会变为 nginx.pid.oldbin)。
  • WINCH --- 让 master 关闭(优雅回收)自己的 worker 进程(常用于关闭旧 master 的 workers)。
  • QUIT --- 优雅退出(master/worker 都会优雅退出)。
  • HUP --- 重新载入配置,master 平滑替换 worker(会生成新 worker 并优雅停止旧 worker)。
  • TERM/INT --- 快速退出(不推荐用于正常回收)。

升级前准备(构建新二进制)

​ 1.在目标服务器上备份当前运行的 nginx 二进制:

复制代码
[root@Nginx ]# cd /usr/local/nginx/sbin/
[root@Nginx sbin]# ls
nginx
[root@Nginx sbin]cp -p nginx     nginx.old

2.下载并解压新版本源代码,编译得到新二进制(通常在 objs/nginx)。

复制代码
[root@Nginx ~]wget https://nginx.org/download/nginx-1.29.4.tar.gz
bash 复制代码
[root@Nginx ~] tar zxf nginx-1.29.4.tar.gz
[root@Nginx nginx-1.29.4] ./configure   --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
复制代码
[root@Nginx nginx-1.29.4] make
# 新二进制位于: ./objs/nginx

平滑升级步骤(零停机)

  1. 把新二进制复制到 sbin(覆盖或先改名再替换):

    bash 复制代码
    # 直接替换(已备份旧二进制为 nginx.old)
    [root@Nginx objs]# cd /usr/local/nginx/sbin/
    [root@Nginx sbin]\cp -f /root/nginx-1.29.4/objs/nginx  /usr/local/nginx/sbin/nginx#新的nginx覆盖旧的nginx
  2. 找到当前 master 进程 PID(或从 nginx.pid 文件读取):

    bash 复制代码
    OLD_MASTER_PID=$(cat /usr/local/nginx/logs/nginx.pid)
    #或用进程命令查PID ps aux | grep nginx
  3. 发送 USR2 信号,让旧 master 启动新 master(新 binary):

    bash 复制代码
    kill -USR2 $OLD_MASTER_PID
    或用 kill -USR2 875--查到的masterpid

    结果:会出现新的 master 进程(新 binary),并生成 nginx.pid.oldbin(记录旧 master 的 PID);新 master 启动后会有自己的 worker。

  4. 验证新 master 已启动并正常工作:

    bash 复制代码
    ps aux | egrep 'nginx: master|nginx: worker'或 ps aux | grep nginx
    # 或查看新 master 的 PID 和 nginx -V
    /usr/local/nginx/sbin/nginx -V
    # 检查日志:/usr/local/nginx/logs/error.log
    复制代码
    成功后可以查到两个pid文件[root@Nginx sbin]# ls /usr/local/nginx/logs/
  5. 若新 master 工作正常,优雅回收旧的 worker(让旧 master 停止其 worker):

    bash 复制代码
    # 让旧 master 回收其 worker(OLD_MASTER_PID)
    kill -WINCH $OLD_MASTER_PID
    或kill -WINCH 875--旧进程master-pid

    此后,新 master 与其 worker 继续提供服务;旧 master本身仍在(可 later QUIT 清理)。

  6. 清理旧 master:

    • 如果确认不再需要旧 master,可优雅退出旧 master:

      bash 复制代码
      kill -QUIT $OLD_MASTER_PID
    • 删除备份或按命名策略保留:nginx.old 可删除或存档。


验证要点

  • 确认只有新二进制的 workers 在提供流量(ps/ss/netstat/check logs)。
  • 通过 curl、健康检查或流量探针验证请求正常。
  • nginx -V 输出应能反映 new build 的信息(注意 path 若 PATH 指向旧 binary,需指定完整路径)。

回滚(若新版本异常)

回滚(若新版本异常)

场景 A --- 尚未回收旧 worker(尚未对旧 master 发 WINCH):

  • 如果旧 master 仍在且其 workers 仍提供服务,你可以直接停止新 master 并让旧 master继续:

    bash 复制代码
    # 找到 new master PID(比如 NEW_MASTER_PID)
    kill -QUIT 新pid
    # 优雅停止 new master 及其 workers
    # 如果你已经替换了 /usr/local/nginx/sbin/nginx 为新 binary,建议把旧 binary 恢复:
    \cp -pf /usr/local/nginx/sbin/nginx.old /usr/local/nginx/sbin/nginx

场景 B--- 已对旧 master 发 WINCH(旧 workers 已被回收):

  • 要回到旧二进制并恢复旧 master 的 workers:

    复制代码
    [root@Nginx sbin]# cd /usr/local/nginx/sbin/
    [root@Nginx sbin]# cp nginx nginx.new -p 备份新的nginx
    复制代码
    [root@Nginx sbin]# \cp nginx.old  nginx -pf 回滚旧的nginx
    [root@nginx sbin]# ps aux | grep nginx
    [root@nginx sbin]# kill -HUP 875 唤醒旧nginx进程
    [root@Nginx sbin]# nginx -V

    回滚完成

场景 B 二 已对旧 master 发 WINCH(旧 workers 已被回收):

  • 要回到旧二进制并恢复旧 master 的 workers:

    1. 停止新 master(优雅):

      bash 复制代码
      kill -QUIT pid
    2. 恢复旧二进制文件到 sbin(如果已被替换):

      bash 复制代码
      [root@Nginx sbin]# \cp nginx.old  nginx -pf
    3. 让旧 master 重新 spawn worker(向旧 master 发送 HUP):

      bash 复制代码
      kill -HUP pid

      这会让旧 master 重新加载配置并启动新的 worker(以旧二进制继续提供服务)。

  • 最终确认:

    bash 复制代码
    ps aux | egrep 'nginx: master|nginx: worker'
    nginx -V   # 应显示旧版本信息

其他注意事项与建议

  • 模块兼容性:如果新旧二进制使用了不兼容的第三方模块或不同的编译选项,平滑替换可能失败或出现问题。确保新版本在测试环境中通过。
  • 日志文件:升级/回滚时注意日志文件句柄是否已正确 reopened(HUP 会让 master 重新打开日志)。
  • systemd 管理的服务:如果你用 systemd 管理 nginx(systemctl start/stop),上面基于信号的手动流 程仍然有效,但要注意 systemd 对进程的管理(PIDFile 配置)。在使用 systemd 的场景下,最好先停止通过 systemd 启动的服务再使用手动方式,或通过 systemd 执行升级脚本并同步更新 unit 文件(慎用)。
  • 权限与 SELinux:替换二进制后确认权限(x 位)和 SELinux context(若启用)正确;必要时用 restoreconchcon
  • 备份策略:保留 nginx.old 若干天以便快速回滚;在自动化脚本里按时间戳保存(如 nginx-1.28.1_20260131)。
  • 自动化:将升级/回滚步骤写入脚本并先在预发布环境演练,脚本应包含检查、回滚点与日志记录。

常用命令汇总

bash 复制代码
# 备份当前二进制
cp -p /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old

# 复制新二进制到 sbin
\cp -f /root/nginx-1.29.4/objs/nginx /usr/local/nginx/sbin/nginx
chmod +x /usr/local/nginx/sbin/nginx

# 取得旧 master pid
OLD_MASTER_PID=$(cat /usr/local/nginx/logs/nginx.pid)

# 启动新 master(平滑升级)
kill -USR2 $OLD_MASTER_PID

# 查看进程
ps aux | egrep 'nginx: master|nginx: worker'

# 优雅回收旧 workers
kill -WINCH $OLD_MASTER_PID

# 优雅停止旧 master(回收后可执行)
kill -QUIT $OLD_MASTER_PID

# 回滚(停止 new master)
kill -QUIT $NEW_MASTER_PID

# 恢复旧二进制并让旧 master spawn worker(若已 WINCH)
\cp -pf /usr/local/nginx/sbin/nginx.old /usr/local/nginx/sbin/nginx
kill -HUP $OLD_MASTER_PID

停止旧 master(回收后可执行)
kill -QUIT $OLD_MASTER_PID

# 回滚(停止 new master)
kill -QUIT $NEW_MASTER_PID

# 恢复旧二进制并让旧 master spawn worker(若已 WINCH)
\cp -pf /usr/local/nginx/sbin/nginx.old /usr/local/nginx/sbin/nginx
kill -HUP $OLD_MASTER_PID
相关推荐
cyber_两只龙宝13 小时前
Nginx--企业高性能web服务器高级配置详解
linux·运维·nginx·云原生
如若12314 小时前
AutoDL云服务器 NVIDIA 570驱动 EGL渲染修复全记录
运维·服务器·python
i建模14 小时前
Omarchy设置防火墙
linux·运维
晚秋大魔王14 小时前
泰拉瑞亚手机版服务器部署
运维·服务器·泰拉瑞亚
敲代码的哈吉蜂14 小时前
高可用集群Keepalived
运维·服务器·网络·数据库
盟接之桥15 小时前
盟接之桥说制造:从客供的外在共生到内在的身心合一
运维·服务器·网络·人工智能·制造
火车叼位16 小时前
让 SSL 证书管理更简单:k ssl 命令实战手册
运维
礼拜天没时间.16 小时前
JumpServer堡垒机部署与实战:从0到1搭建统一运维入口
linux·运维·架构·堡垒机·jumpserver·sre
林姜泽樾16 小时前
linux入门第四章,cd指令和相对、绝对路径
linux·运维·服务器
是小崔啊17 小时前
叩丁狼k8s-运维管理
运维·容器·kubernetes