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 准备阶段

  1. 确认当前运行状态

    ps -ef | grep nginx
    nginx -V  # 查看版本及编译参数(记录 --prefix 路径)
    
  2. 下载并解压新版本源码

    cd /root
    tar xvf nginx-1.26.2.tar.gz
    cd nginx-1.26.2
    
  3. 安装依赖(如缺失)

    yum install -y openssl-devel pcre-devel
    
  4. 配置编译参数(必须与原版本一致)

    ./configure \
      --prefix=/usr/local/nginx \
      --user=www --group=www \
      --with-http_ssl_module \
      --with-http_stub_status_module \
      --with-http_realip_module
    
  5. 编译并安装(不执行 make install 会覆盖原文件)

    make && make install
    
    • 执行后,原 sbin/nginx 自动备份为 sbin/nginx.old
    • 新二进制文件写入 sbin/nginx

3.2 平滑升级阶段(关键!)

所有操作基于旧 Master 进程 PID

  1. 查看当前进程

    ps aux | grep nginx
    # 示例输出:
    # root     93651  ... nginx: master process ...
    # www      93652  ... nginx: worker process ...
    
  2. 发送 USR2 信号:启动新 Master

    kill -USR2 93651
    
    • 系统会启动 新版本 Master 进程(PID 如 110729);
    • 新 Master 启动对应的新 Worker;
    • 此时:2 个 Master + 2 个 Worker 并存。
  3. 发送 WINCH 信号:优雅关闭旧 Worker

    kill -WINCH 93651
    
    • 旧 Master 不再接受新连接,并逐步关闭其 Worker;
    • 旧请求继续处理直至完成;
    • 新请求全部由新版本处理。
  4. 确认无误后,发送 QUIT 信号:关闭旧 Master

    kill -QUIT 93651
    
    • 旧 Master 进程退出;
    • 最终仅剩 新版本 Master + Worker

⚠️ 若执行 QUIT 后两个 Master 都退出,可能是混用了 systemctl 和原生命令,导致进程关系异常。


3.3 验证阶段

  1. 检查进程

    ps -ef | grep nginx  # 应仅有一个 Master 和 Worker
    
  2. 验证版本

    /usr/local/nginx/sbin/nginx -v        # 新版本
    /usr/local/nginx/sbin/nginx.old -v    # 旧版本(备份)
    
  3. 业务验证

    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 响应头

提示:实际操作前务必在测试环境演练,避免生产事故。

posted @ 2026-01-12 16:34  ShiLiCoder  阅读(7)  评论(0)    收藏  举报