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)
执行效果:
- 系统生成
nginx.pid.oldbin,保存旧 master pid - 新旧两套 master+worker 同时运行
- 流量由新旧进程共同处理,业务零中断
验证进程:
ps -ef | grep nginx
4. 发送 winch 信号:优雅关闭旧 worker 进程
kill -winch $(cat /usr/local/nginx/logs/nginx.pid.oldbin)
执行效果(新手必懂):
- 旧 worker 进程消失,不再接收新请求
- 旧 master 进程保留(用于兜底回滚)
- 所有新流量切换到新版 nginx,存量长连接继续跑完,自动释放
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保姆级平滑升级的资料请关注代码网其它相关文章!
发表评论