当前位置: 首页 > ai >正文

Nginx 实战系列(三)—— Nginx 版本升级之普通升级与平滑升级

文章目录

  • 前言
  • 一、升级前准备:这些前提不能少
    • 1.1 确认当前 Nginx 信息
    • 1.2 下载目标版本 Nginx
    • 1.3 备份关键文件
  • 二、方案一:普通升级(停止服务升级)
    • 2.1 停止当前 Nginx 服务
    • 2.2 编译新版本 Nginx
    • 2.3 替换二进制文件并启动
    • 2.4 验证升级结果
  • 三、方案二:平滑升级(无感知不中断)
    • 3.1 核心原理:Nginx 信号机制
    • 3.2 操作步骤
      • 3.2.1 前期准备(同方案一)
      • 3.2.2 复制新版本二进制文件
      • 3.2.3 发送信号启动新版本主进程
      • 3.2.4 逐步关闭旧版本工作进程
      • 3.2.5 验证新版本并收尾
  • 四、升级失败回滚方案
    • 4.1 普通升级回滚
    • 4.2 平滑升级回滚
  • 五、常见问题与注意事项
  • 总结:两种升级方案对比

前言

在服务器运维工作中,Nginx 作为高性能的 Web 服务器和反向代理,其版本更新不仅能修复已知漏洞、提升稳定性,还可能带来新的功能特性。但升级过程中如何保障业务不中断?本文将详细对比 普通升级平滑升级 两种方案,从原理、操作步骤到注意事项,带你完整掌握 Nginx 版本升级流程。

PS:如果想了解如何安装配置Nginx,可以参考Nginx 实战系列(一)—— Web 核心概念、HTTP/HTTPS协议 与 Nginx 安装

一、升级前准备:这些前提不能少

无论选择哪种升级方式,前期准备工作都是保障升级成功的基础,主要包括以下 3 点:

1.1 确认当前 Nginx 信息

首先需要了解当前 Nginx 的版本、编译参数和运行状态,避免升级后出现配置不兼容或功能缺失问题。

# 1. 查看当前 Nginx 版本
nginx -v  # 简洁版本信息,如 nginx version: nginx/1.20.0
nginx -V  # 完整信息(含编译参数),重点记录 --prefix、--with-xxx 等参数

在这里插入图片描述

# 2. 查看 Nginx 运行状态
systemctl status nginx  # 系统服务管理(CentOS/RHEL 7+、Ubuntu 16.04+)
# 或通过进程查看
ps -aux | grep nginx  # 区分主进程(master)和工作进程(worker)

在这里插入图片描述
在这里插入图片描述

1.2 下载目标版本 Nginx

从 Nginx 官方网站下载稳定版(Stable Version)源码包,推荐选择长期支持的版本(如 1.22.x、1.24.x),避免使用开发版(Mainline Version)用于生产环境。

  • 官方下载地址:nginx.org/en/download.html
  • 下载命令(以 1.22.0 为例):
# 进入源码存放目录(如 /opt)
cd /opt
# 下载源码包
wget https://nginx.org/download/nginx-1.22.0.tar.gz
# 解压
tar -zxvf nginx-1.22.0.tar.gz
cd nginx-1.22.0

在这里插入图片描述
在这里插入图片描述

1.3 备份关键文件

升级前必须备份 配置文件旧版本二进制文件,防止升级失败后无法回滚:

# 1. 备份 Nginx 配置文件(默认路径为 --prefix 指定的 conf 目录)
cp -r /usr/local/nginx/conf /usr/local/nginx/conf_bak_$(date +%Y%m%d)

在这里插入图片描述

# 2. 备份 Nginx 日志文件(可选,避免日志丢失)
cp -r /usr/local/nginx/logs /usr/local/nginx/logs_bak_$(date +%Y%m%d)

在这里插入图片描述

# 3. 备份旧版本二进制文件(后续会用到)
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_old

在这里插入图片描述

二、方案一:普通升级(停止服务升级)

普通升级的核心逻辑是 先停止旧版本 Nginx,再替换二进制文件并启动新版本。这种方式操作简单,但会导致服务短暂中断(通常几秒到几十秒),适合非核心业务或可接受短时间停机的场景。具体操作步骤如下:

2.1 停止当前 Nginx 服务

确保所有连接断开后再停止服务,避免数据丢失:

# 方式1:通过系统服务停止(推荐,兼容 systemd)
systemctl stop nginx# 方式2:通过 Nginx 自身命令停止
nginx -s stop  # 快速停止(可能中断正在处理的请求)
# 或
nginx -s quit  # 优雅停止(等待所有请求处理完成后停止)

在这里插入图片描述

2.2 编译新版本 Nginx

编译参数必须与旧版本一致(参考第一步 nginx -V 输出的参数),否则可能导致配置不兼容或功能缺失:

# 进入解压后的新版本目录
cd /opt/nginx-1.22.0# 执行 configure 配置(参数与旧版本保持一致)
./configure \
--prefix=/usr/local/nginx \  # 安装路径(与旧版本相同)
--user=nginx \               # 运行用户
--group=nginx \              # 运行用户组
--with-http_stub_status_module \  # 状态监控模块
--with-http_ssl_module        # HTTPS 模块(若旧版本有则保留)#无注释版:
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module \
--with-http_ssl_module

在这里插入图片描述

# 编译(无需执行 make install,避免覆盖配置文件)
make

2.3 替换二进制文件并启动

编译完成后,新版本二进制文件会生成在 objs/nginx 路径,将其复制到旧版本路径:

# 复制新版本二进制文件到运行目录
cp objs/nginx /usr/local/nginx/sbin/

在这里插入图片描述
在这里插入图片描述

# 启动新版本 Nginx
systemctl start nginx
# 或
nginx

2.4 验证升级结果

确认 Nginx 版本和服务状态是否正常:

# 查看版本(应显示目标版本 1.22.0)
nginx -v# 查看服务状态(确保为 active (running))
systemctl status nginx# 访问测试(若有 Web 服务,通过浏览器或 curl 验证)
curl http://localhost

在这里插入图片描述

三、方案二:平滑升级(无感知不中断)

平滑升级是 Nginx 的核心特性之一,其原理是 不停止旧版本主进程,通过信号控制逐步替换工作进程,整个过程中服务不中断,新请求由新版本处理,旧请求处理完成后旧进程退出,适合生产环境(尤其是核心业务)。

3.1 核心原理:Nginx 信号机制

Nginx 主进程(master)通过接收特定信号实现进程管理,平滑升级依赖以下 3 个关键信号:

  • USR2:主进程接收到后,会启动一个新版本的主进程,并继承旧版本的监听端口和配置;
  • WINCH:旧版本主进程接收到后,会逐步关闭所有旧版本工作进程(worker);
  • QUIT:优雅关闭主进程(等待所有工作进程结束后退出)。

3.2 操作步骤

3.2.1 前期准备(同方案一)

完成版本确认、源码下载、文件备份和新版本编译(步骤与方案一的 1~2 一致,确保 make 编译完成)。

3.2.2 复制新版本二进制文件

直接替换旧版本二进制文件(此时旧进程仍在运行,不影响服务):

# 备份旧版本二进制文件(若未备份可执行)
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx_old# 复制新版本二进制文件(同方案一)
cp /opt/nginx-1.22.0/objs/nginx /usr/local/nginx/sbin/nginx

在这里插入图片描述

3.2.3 发送信号启动新版本主进程

先找到旧版本 Nginx 主进程的 PID(通过 ps -aux | grep nginx 查看,通常是第一个 nginx 进程):

# 1. 查找旧版本主进程 PID(示例 PID 为 4787)
ps -aux | grep nginx
# 输出示例:root  4787  0.0  0.0  46008  1128 ? Ss   18:03   0:00 nginx: master process /usr/local/nginx/sbin/nginx

在这里插入图片描述

# 2. 发送 USR2 信号,启动新版本主进程
kill -USR2 4787# 3. 再次查看进程,会发现两个主进程(旧 4787 + 新 PID,如 20345)
ps -aux | grep nginx

在这里插入图片描述

3.2.4 逐步关闭旧版本工作进程

新版本主进程启动后,会自动创建新版本工作进程,此时需要关闭旧版本工作进程:

# 发送 WINCH 信号给旧版本主进程,关闭旧工作进程
kill -WINCH 4787# 查看进程:旧工作进程会逐步退出,仅剩旧主进程(4787)和新主进程+新工作进程
ps -aux | grep nginx

在这里插入图片描述

3.2.5 验证新版本并收尾

确认新版本正常运行后,可彻底关闭旧版本主进程(若出现问题,可通过旧主进程回滚):

# 1. 验证新版本(此时 nginx -V 已指向新版本)
nginx -V  # 应显示 1.22.0,且编译参数正确# 2. 访问测试(通过浏览器或 curl 确认服务正常)
curl http://localhost# 3. 彻底关闭旧版本主进程(升级无问题后执行)
kill -s QUIT 4787# 4. 再次查看进程:仅保留新版本主进程和工作进程
ps -aux | grep nginx

在这里插入图片描述

四、升级失败回滚方案

无论哪种升级方式,都需提前准备回滚方案,确保出现问题时能快速恢复服务。

4.1 普通升级回滚

若启动新版本后服务异常,直接恢复旧版本二进制文件并重启:

# 1. 停止新版本 Nginx
systemctl stop nginx# 2. 恢复旧版本二进制文件
mv /usr/local/nginx/sbin/nginx_old /usr/local/nginx/sbin/nginx# 3. 启动旧版本 Nginx
systemctl start nginx# 4. 验证回滚结果
nginx -v  # 应显示旧版本

4.2 平滑升级回滚

若平滑升级后发现问题,通过旧版本主进程恢复服务:

# 1. 发送 HUP 信号给旧版本主进程,重启旧版本工作进程
kill -s HUP 旧主进程PID(如 4787# 2. 发送 QUIT 信号给新版本主进程,关闭新版本
kill -s QUIT 新主进程PID(如 20345# 3. 恢复旧版本二进制文件
mv /usr/local/nginx/sbin/nginx_old /usr/local/nginx/sbin/nginx# 4. 验证回滚结果
nginx -v  # 应显示旧版本
ps -aux | grep nginx  # 仅保留旧版本进程

在这里插入图片描述

五、常见问题与注意事项

  1. 编译参数不一致导致启动失败
    问题现象:nginx -t 报配置错误,或启动后服务异常。
    解决:必须确保新版本 ./configure 参数与旧版本完全一致(参考 nginx -V 输出),缺失模块会导致配置不兼容。

  2. 权限问题导致无法启动
    问题现象:启动时提示 permission denied
    解决:检查 nginx 二进制文件权限(建议 chmod 755 /usr/local/nginx/sbin/nginx),且运行用户(如 nginx)对日志目录、配置目录有读写权限。

  3. 平滑升级后旧主进程无法关闭
    问题现象:执行 kill -QUIT 旧主进程PID 后,旧主进程仍存在。
    解决:先检查是否有未结束的旧工作进程(ps -aux| grep nginx),等待其处理完请求后自动退出,或手动发送 TERM 信号强制关闭(kill -s TERM 旧工作进程PID)。

  4. 升级前务必测试配置
    替换二进制文件后,启动前执行 nginx -t 检查配置文件是否兼容新版本,避免因配置语法变化导致启动失败:

    nginx -t  # 输出 nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful 即为正常
    

总结:两种升级方案对比

对比维度普通升级(停止服务)平滑升级(无感知)
服务中断是(短暂中断)否(完全无感知)
操作复杂度低(步骤少)中(需管理信号)
适用场景非核心业务、测试环境生产环境、核心业务
回滚难度低(直接恢复文件)中(需控制进程)

无论选择哪种方案,升级前备份、升级中验证、升级后监控 都是必不可少的环节。通过本文的操作步骤,你可以根据业务场景灵活选择升级方式,确保 Nginx 版本升级安全、高效。

http://www.xdnf.cn/news/20313.html

相关文章:

  • C++ STL系列-02.泛型入门
  • buuctf-鸡藕椒盐味,[NPUCTF2020]EzRSA,[WUSTCTF2020]大数计算
  • Skia如何渲染 Lottie 动画
  • 《Java线程池面试全解析:从原理到实践的高频问题汇总》
  • 深入剖析Spring Boot启动流程
  • 基于Node.js和Three.js的3D模型网页预览器
  • JP4-7-MyLesson后台前端(二)
  • 轻量应用服务器具体指的是什么?
  • Redis《RedisSerializer》
  • 脑电数据预处理十五:小波变换从原理到实践
  • Codeforces Round 1046 (Div. 2) vp补题
  • C++ 详细讲解vector类
  • 检查CDB/PDB 表空间的说明
  • Linux网络接口命名详解:从eth0到ens33
  • [光学原理与应用-431]:非线性光学 - 能生成或改变激光波长的物质或元件有哪些?
  • GPIO的配置中开漏输出与推挽输出的差别
  • C++零基础第四天:顺序、选择与循环结构详解
  • Protobuf
  • 人工智能辅助荧光浓度检测系统:基于YOLO与RGB分析的Python实现
  • 【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
  • AP1272:新一代高性能LDO稳压器,为精密电子系统提供更优电源解决方案
  • 《秦时明月》系列经典语录分享
  • 云原生的12个要素是什么?
  • 【Linux指南】动静态库与链接机制:从原理到实践
  • 疯狂星期四文案网第62天运营日记
  • 消失的6个月!
  • 从文本到知识:使用LLM图转换器构建知识图谱的详细指南
  • Java多线程学习笔记
  • Nginx 实战系列(二)—— Nginx 配置文件与虚拟主机搭建
  • QML Charts组件之LineSeries、SplineSeries与ScatterSeries