nginx平滑升级
Nginx 平滑升级详细笔记(优化整合版)
一、核心概念
1.1 什么是平滑升级?
- 定义:在不停止服务的前提下,将 Nginx 从旧版本无缝升级到新版本。
- 核心原理:
- 新旧版本 Master/Worker 进程并行运行;
- 旧请求由旧 Worker 处理完毕,新请求由新 Worker 处理;
- 升级过程对用户透明,实现 零停机、无感知切换。
1.2 平滑升级 vs 重装升级
| 对比项 | 平滑升级 | 重装升级 |
|---|---|---|
| 是否停服 | 否 | 是 |
| 业务影响 | 无中断 | 服务不可用 |
| 操作复杂度 | 较高(需信号控制) | 简单(删旧装新) |
| 适用场景 | 生产环境、高可用要求 | 测试环境、低可用性要求 |
二、前提条件与限制
2.1 必须使用原生命令启动
- 不支持
systemctl管理的 Nginx 实例进行平滑升级。 - 原因:systemd 的进程管理机制与 Nginx 的多进程模型存在冲突,无法正确处理信号传递和子进程继承。
- 正确方式:
# 先停止 systemd 管理的服务 systemctl stop nginx # 使用原生命令启动(确保 master + worker 正常) /usr/local/nginx/sbin/nginx
2.2 安装路径必须一致
- 新版本编译时必须指定与旧版本相同的
--prefix路径(如/usr/local/nginx)。 - 否则无法覆盖二进制文件,也无法触发自动备份机制。
三、完整操作流程
3.1 准备阶段
-
确认当前运行状态
ps -ef | grep nginx nginx -V # 查看版本及编译参数(记录 --prefix 路径) -
下载并解压新版本源码
cd /root tar xvf nginx-1.26.2.tar.gz cd nginx-1.26.2 -
安装依赖(如缺失)
yum install -y openssl-devel pcre-devel -
配置编译参数(必须与原版本一致)
./configure \ --prefix=/usr/local/nginx \ --user=www --group=www \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-http_realip_module -
编译并安装(不执行 make install 会覆盖原文件)
make && make install- 执行后,原
sbin/nginx自动备份为sbin/nginx.old; - 新二进制文件写入
sbin/nginx。
- 执行后,原
3.2 平滑升级阶段(关键!)
所有操作基于旧 Master 进程 PID
-
查看当前进程
ps aux | grep nginx # 示例输出: # root 93651 ... nginx: master process ... # www 93652 ... nginx: worker process ... -
发送
USR2信号:启动新 Masterkill -USR2 93651- 系统会启动 新版本 Master 进程(PID 如 110729);
- 新 Master 启动对应的新 Worker;
- 此时:2 个 Master + 2 个 Worker 并存。
-
发送
WINCH信号:优雅关闭旧 Workerkill -WINCH 93651- 旧 Master 不再接受新连接,并逐步关闭其 Worker;
- 旧请求继续处理直至完成;
- 新请求全部由新版本处理。
-
确认无误后,发送
QUIT信号:关闭旧 Masterkill -QUIT 93651- 旧 Master 进程退出;
- 最终仅剩 新版本 Master + Worker。
⚠️ 若执行
QUIT后两个 Master 都退出,可能是混用了systemctl和原生命令,导致进程关系异常。
3.3 验证阶段
-
检查进程
ps -ef | grep nginx # 应仅有一个 Master 和 Worker -
验证版本
/usr/local/nginx/sbin/nginx -v # 新版本 /usr/local/nginx/sbin/nginx.old -v # 旧版本(备份) -
业务验证
echo "hello nginx" > /usr/local/nginx/html/index.html curl -I http://localhost- 检查响应头中的
Server: nginx/1.26.2; - HTTP 状态码应为
200。
- 检查响应头中的
四、关键命令与信号说明
| 信号 | 命令示例 | 作用 | 注意事项 |
|---|---|---|---|
-USR2 |
kill -USR2 <old_master_pid> |
启动新版本 Master 进程 | 必须作用于 旧 Master PID |
-WINCH |
kill -WINCH <old_master_pid> |
优雅关闭旧 Worker 进程 | 旧请求处理完才退出 |
-QUIT |
kill -QUIT <old_master_pid> |
优雅关闭旧 Master 进程 | 确认无流量后再执行 |
✅ 顺序不可颠倒:
USR2 → WINCH → QUIT
五、目录与文件结构
| 路径 | 说明 |
|---|---|
/usr/local/nginx/sbin/nginx |
当前运行的 Nginx 二进制文件 |
/usr/local/nginx/sbin/nginx.old |
升级前自动备份的旧版本 |
/usr/local/nginx/conf/nginx.conf |
主配置文件 |
/usr/local/nginx/logs/ |
日志目录(access.log, error.log) |
六、常见问题与注意事项
-
Q:为什么不能用
systemctl管理的 Nginx 做平滑升级?
A:systemd 无法正确传递信号给 Nginx 子进程,且进程树结构不符合 LNX 平滑升级要求。 -
Q:升级失败如何回滚?
A:直接用nginx.old启动即可:/usr/local/nginx/sbin/nginx.old -c /usr/local/nginx/conf/nginx.conf -
Q:是否需要重启整个服务?
A:不需要。整个过程无需重启,靠信号控制进程生命周期。 -
Q:新旧版本能否长期共存?
A:可以短期共存(用于灰度或回滚),但不建议长期,会占用额外内存和端口资源。
七、适用场景
- 高可用 Web 服务(如电商、金融、SaaS 平台)
- 7×24 小时不间断业务系统
- 对 SLA 要求严格的生产环境
典型对比:Nginx 支持平滑升级,而 MySQL 通常需停服升级(除非使用主从切换等高可用方案)。
八、知识小结(速记)
- 平滑升级 = 不停服 + 新旧共存 + 信号控制
- 三大信号:USR2(启新)、WINCH(关旧Worker)、QUIT(关旧Master)
- 必须原生命令启动,禁用 systemctl
- 编译路径必须一致,自动备份为 nginx.old
- 验证:进程数、版本号、curl 响应头
提示:实际操作前务必在测试环境演练,避免生产事故。

浙公网安备 33010602011771号