nginx

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > nginx > Nginx保姆级平滑升级

Nginx平滑升级的保姆级教程

作者:我科绝伦(Huanhuan Zhou)

生产环境中的 Nginx,常因漏洞修复、版本迭代、新增模块而需要升级,所以本文手把手教你零中断平滑升级的完整流程,从备份、编译到USR2信号切换流量,附真实报错复盘和一键回滚方案,照搬即可,确保业务不中断,需要的朋友可以参考下

0 业务中断 · 含备份 + 全程命令 + 报错复盘 + 回滚方案

生产环境升级 Nginx,最怕什么?停服、报错、回不去。
这篇文章,手把手带你走一遍 零中断、可回滚 的平滑升级全流程,附真实踩坑复盘,照搬即可。

一、前言:为什么必须“平滑升级”?

生产环境中的 Nginx,常因漏洞修复、版本迭代、新增模块而需要升级。

传统方式——停服务 → 删旧版 → 装新版 → 启服务——会造成:

而 Nginx 平滑升级 依托多进程热替换机制,可实现:

本文基于 CentOS 7 + Nginx 编译安装,所有步骤均经真实实操验证,零基础运维可直接复制执行。

二、核心原理(搞懂这 4 个信号,避坑 80%)

Nginx 平滑升级依赖 4 个关键信号,新旧进程像接力赛一样交替:

信号作用时机
USR2启动全新版本的 Master+Worker 进程,新旧共存升级开始
WINCH优雅关闭旧版 Worker,不再接新流量,存量连接跑完流量切换
QUIT优雅退出旧版 Master,彻底完成升级业务验证后
HUP平滑重载配置(日常修改配置用)不升级时

黄金法则:编译时的 --prefix 安装路径 必须 与当前运行的 Nginx 原路径 完全一致,否则新进程读不到配置文件,直接启动失败——这是本文最大的踩坑点,下文会详细复盘。

三、升级前准备(生产必做:备份 + 环境校验)

1. 全量备份旧 Nginx(保命操作)

无备份不升级!备份可实现 1 分钟极速回滚所有配置、日志、二进制。

tar -zcvf /usr/local/nginx-backup-$(date +%F).tar.gz /usr/local/nginx/

建议同时备份到其他目录或远程存储,双重保险。

2. 查看旧版本编译参数(重中之重)

新版本编译时,必须保留旧版所有参数,可新增模块,但绝不可删减,否则会导致模块缺失、升级失败。

/usr/local/nginx/sbin/nginx -V

本次实操原有参数(请替换为你自己的):

--prefix=/usr/local/nginx \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module

3. 安装编译依赖,一般不需要额外安装依赖

yum install -y gcc make zlib-devel pcre-devel openssl-devel wget

四、新版本编译(核心避坑:只make,不make install)

1. 下载新版 Nginx 源码

本次升级示例版本:nginx-1.30.4(最新稳定版)

wget https://nginx.org/download/nginx-1.30.4.tar.gz #这个路径随便哪里都行
tar -zxvf nginx-1.30.4.tar.gz
cd nginx-1.30.4

2. 同源路径编译(解决核心报错)

❌ 错误示范:首次编译时指定 --prefix=/data/nginx,与运行路径 /usr/local/nginx 不一致,导致新进程找不到配置文件,USR2 信号失效。

✅ 正确操作:--prefix 必须与旧版安装路径 完全一致。

./configure --prefix=/usr/local/nginx \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-pcre \
--with-stream \
--with-stream_ssl_module

3. 编译(关键禁忌:绝对不要make install)

make

make install 会强制覆盖配置文件和目录结构,极大概率丢失业务配置。平滑升级只需要 make 生成新二进制即可,切勿执行 make install。

五、正式平滑升级(0 业务中断,全程步骤)

1. 备份旧版二进制程序

cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak.$(date +%F)

2. 替换新版二进制程序

cp objs/nginx /usr/local/nginx/sbin/nginx 

校验版本,确认替换成功:

/usr/local/nginx/sbin/nginx -V

此时应显示 nginx/1.30.4。

3. 发送 USR2 信号:启动新进程(双进程运行)

kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)

执行效果:

验证进程:

ps -ef | grep nginx

4. 发送 WINCH 信号:优雅关闭旧 Worker 进程

kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid.oldbin)

执行效果(新手必懂):

5. 业务验证(升级最关键的一步)

务必验证业务访问、接口、页面正常,无 404/502/SSL 异常后,再收尾!

# 校验配置语法
/usr/local/nginx/sbin/nginx -t

# 查看端口监听
netstat -lntup | grep nginx

# 查看错误日志
tail -20 /usr/local/nginx/logs/error.log

如果发现问题,立刻回滚(见第七部分),不要犹豫。

6. 发送 QUIT 信号:彻底结束旧进程(收尾)

业务确认完全正常后,优雅退出旧 Master:

kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)

7. 最终状态验证

# 仅剩新版 Master+Worker
ps -ef | grep nginx

# 确认最终版本
/usr/local/nginx/sbin/nginx -V

升级完成!

六、本次实操核心报错复盘(全网最精准避坑)

报错现象

执行 kill -USR2 后无新进程生成,错误日志显示:

open() "/data/nginx/conf/nginx.conf" failed (2: No such file or directory)

根因分析

Nginx 编译时,--prefix 路径会硬编码进二进制程序。首次编译时指定了 /data/nginx,但实际运行路径是 /usr/local/nginx。
替换二进制后,新进程强制读取 /data/nginx/conf/nginx.conf,文件不存在,启动失败,自然无新进程。

解决方案

重新执行 ./configure,确保 --prefix 与当前运行路径一致,重新 make 并替换二进制即可。

七、一键回滚方案(升级失败救命)

若升级后出现异常,10 秒极速回滚,无需停机。

方式 1:回滚二进制(推荐,最快)

# 还原旧版执行文件
cp /usr/local/nginx/sbin/nginx.bak.$(date +%F) /usr/local/nginx/sbin/nginx

# 重新热升级回滚旧版本
kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)

方式 2:全目录回滚(彻底还原所有配置)

# 解压之前的全量备份
tar -zxvf /usr/local/nginx-backup-$(date +%F).tar.gz -C /

# 重载配置
/usr/local/nginx/sbin/nginx -s reload

建议优先用方式 1,速度最快;方式 2 适合配置也乱掉的情况。

八、Nginx 核心信号命令大全(运维常备)

命令用途
nginx -s reload平滑重载配置(日常改配置)
kill -USR2 PID启动新版本进程(升级第一步)
kill -WINCH PID关闭旧 Worker,切换流量
kill -QUIT PID优雅退出旧 Master(升级收尾)
nginx -s stop快速停止(不推荐生产)
nginx -s quit优雅停止

九、最终总结(生产升级口诀)

📌 先备份,后操作——无备份绝不升级
📌 参数同源——新版 --prefix 和模块参数必须与旧版一致
📌 只 make 不 install——避免覆盖业务配置
📌 三步升级——USR2 双进程 → WINCH 切流量 → QUIT 清旧进程
📌 先验证再收尾——业务正常再结束旧进程,保留回滚机会

以上就是Nginx平滑升级的保姆级教程的详细内容,更多关于Nginx保姆级平滑升级的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文