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
相关推荐
网硕互联的小客服2 小时前
linux服务器忘记远程端口怎么办?如何找回?
linux·运维·服务器
历程里程碑2 小时前
Linux 16 环境变量
linux·运维·服务器·开发语言·数据库·c++·笔记
ZeroNews内网穿透2 小时前
关于飞牛fnOS重要安全更新的提醒
运维·服务器·web安全·ssh
故乡de云2 小时前
2026年谷歌云价格走势深度分析:企业如何在高成本时代保持竞争力?
运维·kubernetes·云计算
j_xxx404_3 小时前
Linux:自主shell命令行解释器附源码
linux·运维·服务器
何以不说话3 小时前
堡垒机jumpserver
运维·sql
开开心心就好3 小时前
开源免费高速看图工具,支持漫画大图秒开
linux·运维·服务器·安全·ruby·symfony·1024程序员节
小Pawn爷3 小时前
13.virtualbox安装ubuntu
linux·运维·ubuntu
乾元4 小时前
暗网情报:自动化采集与情感分析在威胁狩猎中的应用
运维·网络·人工智能·深度学习·安全·架构·自动化