Nginx 生产环境平滑升级实战:从 1.24.0 到 1.28.0 的零宕机操作全记录

在生产环境中升级 Nginx 一直是运维兄弟们最谨慎的操作之一,因为它通常直接暴露在公网,承载着大量的流量,任何一点宕机或配置错误都可能造成业务影响。本文记录了一次真实的线上 Nginx 升级过程:从 1.24.0 升级到 1.28.0 ,全程实现零宕机,并且采用最安全的"二进制文件替换"方式,避免在生产机器上编译。

一、背景与环境

  • 机器信息:CentOS 7(内核 3.10),源码编译安装的 Nginx

  • binary 路径/usr/local/nginx/sbin/nginx

  • 配置路径/etc/nginx/(配置文件为 /etc/nginx/nginx.conf

  • 当前版本:nginx/1.24.0

  • 目标版本:nginx/1.28.0

  • 运行方式 :手动启动(非 systemd 管理),但进程手动启动也长期正常运行

  • 特点:无第三方动态模块,编译参数相对简单

二、为什么选择"只替换 binary"的方式?

常见的 Nginx 升级方式有三种:

  1. 直接在生产机源码编译 + make install

    风险:需要安装开发工具、下载源码、长时间编译,万一依赖缺失或编译失败,可能影响运行中的服务。

  2. 使用 yum/apt 等包管理升级

    不适用:本机为源码安装,无 RPM 包。

  3. 在测试机编译新 binary,只拷贝可执行文件替换 (本次采用)

    优点:

    • 生产机几乎不执行高风险操作
    • 只传输一个几 MB 的二进制文件
    • 支持 Nginx 官方推荐的热二进制替换,实现真正零宕机
    • 保持原有配置、日志、权限完全不变nginx文档

三、升级全过程详解

步骤 1:备份(永远的第一步)

在生产机上备份旧 binary:

bash 复制代码
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx-v1.24.0
步骤 2:获取当前编译参数(最关键!)
复制代码
# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.24.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --user=nginx --group=nginx --prefix=/usr/local/nginx --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --with-pcre-jit --with-http_ssl_module --with-http_v2_module --with-http_sub_module --with-stream --with-stream_ssl_module

输出中重点复制 configure arguments 那一长串(包括 --prefix=/usr/local/nginx),确保新版本用完全相同的参数编译,否则可能缺少模块或路径不一致。

步骤 3:在测试机编译新版本(环境需一致)

选择一台系统、gcc 版本、库版本相近的测试机。

bash 复制代码
cd /tmp
wget https://nginx.org/download/nginx-1.28.0.tar.gz
tar zxvf nginx-1.28.0.tar.gz
cd nginx-1.28.0

./configure [粘贴上面完整的 configure arguments]

make -j$(nproc)    # 快速并行编译(后面的nproc是指最多用多少个核心去编译,如果不写似乎默认是1)

关键提醒不要执行 make install!

编译完成后,新 binary 位于:

bash 复制代码
./objs/nginx

验证版本:

bash 复制代码
./objs/nginx -v
# 输出:nginx version: nginx/1.28.0
步骤 4:传输并替换生产机 binary
bash 复制代码
# 从测试机拷贝到生产机的 /tmp
scp objs/nginx root@生产机IP:/tmp/nginx

# 生产机上替换
cd /usr/local/nginx/sbin
mv /tmp/nginx ./
# 直接覆盖或先备份旧的后再 mv
chmod 755 nginx
步骤 5:验证配置与版本
bash 复制代码
/usr/local/nginx/sbin/nginx -t
# 输出 syntax is ok 和 test is successful

/usr/local/nginx/sbin/nginx -V
# 确认显示 nginx/1.28.0,且 configure arguments 与之前一致
步骤 6:平滑重载(零宕机升级)
bash 复制代码
/usr/local/nginx/sbin/nginx -s reload

原理:Nginx master 进程收到 reload 信号后,会启动新的 worker 进程(使用新 binary),旧 worker 处理完当前连接后自动退出,整个过程无连接中断。

在这一步其实只是用了新的worker,而nginx的架构是master+worker的,但是master的话只是负责读取和校验配置文件、绑定 80/443 等特权端口、创建、管理、监控 worker 进程等,实际上几乎不占资源,如果要重载master的话,可以进行重启操作:

复制代码
$/usr/local/nginx/sbin/nginx -s quit

# 等待一段时间,等到nginx相关进程全部停下来,除了 grep 本身,什么都不应该有
$ps -ef | grep nginx

# 重启nginx
$/usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.conf

四、背后的核心原理

  1. Nginx 的 master-worker 架构

    master 进程负责读取配置、管理 worker;worker 负责实际处理请求。reload 时 master 启动新 worker,旧 worker 优雅退出。

  2. 二进制热替换支持

    Nginx 在启动时会将自身可执行文件路径记录下来。即使你替换了磁盘上的 binary 文件,正在运行的 master 进程仍使用旧的内存镜像。但 reload 后,新 worker 会加载新的 binary,从而实现版本升级。

  3. 为什么只换 binary 就行?

    Nginx 的模块大部分是静态编译进 binary 的(本次无动态模块)。只要编译参数一致,新 binary 就能完美适配原有配置和路径。

五、收尾与建议

  • 观察 /var/log/nginx/error.log 一段时间,确保无异常
  • 可选:切换为 systemd 管理,便于开机自启和统一操作
  • 保留旧 binary 至少一周,以备回滚

六、总结

这次升级全程不到 20 分钟,服务无任何感知,真正实现了生产环境的平滑升级。核心经验就是:

  • 备份永远第一位
  • 编译参数必须一模一样(尤其是 --prefix)
  • 优先选择"只替换 binary"的最小侵入方式
  • 利用 Nginx 自身平滑重载机制实现零宕机

这种方法特别适合老旧生产环境、源码安装、无包管理的场景咯

相关推荐
七夜zippoe6 小时前
CANN Runtime任务描述序列化与持久化源码深度解码
大数据·运维·服务器·cann
Fcy6487 小时前
Linux下 进程(一)(冯诺依曼体系、操作系统、进程基本概念与基本操作)
linux·运维·服务器·进程
袁袁袁袁满7 小时前
Linux怎么查看最新下载的文件
linux·运维·服务器
代码游侠7 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
Harvey9038 小时前
通过 Helm 部署 Nginx 应用的完整标准化步骤
linux·运维·nginx·k8s
珠海西格电力科技9 小时前
微电网能量平衡理论的实现条件在不同场景下有哪些差异?
运维·服务器·网络·人工智能·云计算·智慧城市
释怀不想释怀9 小时前
Linux环境变量
linux·运维·服务器
zzzsde9 小时前
【Linux】进程(4):进程优先级&&调度队列
linux·运维·服务器
聆风吟º11 小时前
CANN开源项目实战指南:使用oam-tools构建自动化故障诊断与运维可观测性体系
运维·开源·自动化·cann
NPE~11 小时前
自动化工具Drissonpage 保姆级教程(含xpath语法)
运维·后端·爬虫·自动化·网络爬虫·xpath·浏览器自动化