Nginx 1.30.4 离线编译与零停机热替换完整手册
⚠️ 前置条件确认
- 当前身份:
root- 旧版 Nginx 前缀:
/usr/local/nginx- 编译依赖:gcc、make、pcre-devel、zlib-devel、openssl-devel 等必须已在离线环境中提前安装。若未安装,需先通过 rpm/deb 包离线安装依赖,否则
./configure会失败。
📥 第一阶段:获取源码与解压
1. 下载 Nginx 1.30.4 源码包
在有网络的机器上下载后,通过 U盘/SCP 等方式传入服务器 /home/zjgzwyjsadmin/ 目录:
# 在联网机器执行示例
wget https://nginx.org/download/nginx-1.30.4.tar.gz2. 解压并进入源码目录
cd /home/nginx-1.30.4
tar -zxvf nginx-1.30.4.tar.gz
cd nginx-1.30.4路径约定后续所有命令均假设源码位于 /home/nginx-1.30.4。若您实际路径不同,请全局替换。
🔧 第二阶段:编译构建(仅编译,不安装)
1. 提取旧版编译参数
OLD_ARGS= $ (nginx -V 2>&1 | grep "configure arguments:" | sed 's/configure arguments: //')
echo "📋 旧版参数: $ OLD_ARGS"2. 配置编译选项
# 使用旧版参数确保模块完全兼容
./configure $ OLD_ARGS3. 编译生成新二进制
# 利用多核加速编译,绝不执行 make install!
make -j $ (nproc)4. 编译后双重验证(必做)
# 验证1:参数一致性(注意 -- 分隔符防止 grep 误解析)
./objs/nginx -V 2>&1 | grep "configure arguments:" | grep -F -- " $ OLD_ARGS" \
&& echo "✅ 编译参数一致" || { echo "❌ 参数不一致,停止!"; exit 1; }
# 验证2:新二进制能正确解析现有配置
./objs/nginx -t
# 期望输出: syntax is ok / test is successful只有两个验证均通过,才能继续。 若失败,检查 $OLD_ARGS 完整性或重新 make clean && make。
🔒 第三阶段:全量备份(不可跳过)
BACKUP_TIME= $ (date +%Y%m%d_%H%M%S)
NGINX_BIN= $ (which nginx)
# 备份二进制
cp " $ NGINX_BIN" " $ {NGINX_BIN}.bak. $ {BACKUP_TIME}"
# 备份配置目录
cp -a /usr/local/nginx/conf "/usr/local/nginx/conf.bak. $ {BACKUP_TIME}"
echo "✅ 备份完成:"
ls -lh " $ {NGINX_BIN}.bak. $ {BACKUP_TIME}"
ls -ld "/usr/local/nginx/conf.bak. $ {BACKUP_TIME}"🔄 第四阶段:零停机热替换执行
💡 原理:USR2 启动新 Master → 新 Worker 接管新请求 → WINCH 优雅关闭旧 Worker
→ QUIT 退出旧 Master。全程无连接中断。
# 确保在源码目录下
cd /home/zjgzwyjsadmin/nginx-1.30.4
NGINX_BIN= $ (which nginx)
# 步骤1:覆盖二进制(旧进程在内存中运行,不受磁盘影响)
cp ./objs/nginx " $ NGINX_BIN"
# 步骤2:启动新 Master 进程
kill -USR2 $ (cat /usr/local/nginx/logs/nginx.pid)
sleep 3
# 步骤3:确认双 Master 共存(必须看到两行 master)
ps aux | grep "[n]ginx: master"
# 步骤4:优雅关闭旧 Worker
kill -WINCH $ (cat /usr/local/nginx/logs/nginx.pid.oldbin)
# 步骤5:业务健康检查(关键决策点!)
curl -sI http://localhost | head -3
tail -20 /usr/local/nginx/logs/error.log | grep -E "emerg|crit|alert"
# ✅ 正常 → 继续步骤6
# ❌ 异常 → 立即执行下方【紧急回滚预案】
# 步骤6:彻底退出旧 Master
kill -QUIT $ (cat /usr/local/nginx/logs/nginx.pid.oldbin)
# 步骤7:最终版本确认
nginx -v
# 期望输出: nginx version: nginx/1.30.4✅ 第五阶段:升级后验证矩阵
| 检查项 | 命令 | 合格标准 | ||
|---|---|---|---|---|
| 版本号 | nginx -v | nginx/1.30.4 | ||
| 进程唯一性 | `ps aux \ | grep "[n]ginx: master" \ | wc -l` | 输出 1 |
| 配置语法 | nginx -t | test is successful | ||
| 错误日志 | tail -20 /usr/local/nginx/logs/error.log | 无新增 emerg/crit | ||
| 业务响应 | curl -sI http://localhost | HTTP 2xx/3xx | ||
| 监听端口 | `ss -tlnp \ | grep nginx` | 所有预期端口 LISTEN |
🔙 紧急回滚预案(30秒内恢复)
仅在第四阶段步骤5健康检查失败时执行:
NGINX_BIN= $ (which nginx)
# ⚠️ 将下方时间戳替换为第三阶段输出的实际 BACKUP_TIME
BACKUP_TIME="YYYYMMDD_HHMMSS"
# 1. 终止新进程组
kill -QUIT $ (cat /usr/local/nginx/logs/nginx.pid) 2>/dev/null
# 2. 恢复旧二进制
cp " $ {NGINX_BIN}.bak. $ {BACKUP_TIME}" " $ NGINX_BIN"
# 3. 重启旧版本
nginx -t && nginx
# 4. 验证回滚成功
nginx -v && curl -sI http://localhost⚠️ Root 环境安全警告
- SELinux:若启用,覆盖二进制后必须执行 restorecon -v "$NGINX_BIN",否则新 Master 无法绑定端口。
- WINCH 耐心等待:WebSocket/大文件下载等长连接可能导致旧 Worker 持续数分钟。用 watch -n1 'ps aux | grep "[n]ginx: worker"' 监控,绝不要 kill -9。
- PID 路径:以上命令假设 PID 在 /usr/local/nginx/logs/nginx.pid。若不同,通过 nginx -V 2>&1 | grep -oP '(?<=--pid-path=)\S+' 获取实际路径并全局替换。
- 操作窗口:尽管零停机,仍建议在业务低峰期执行。
- 离线依赖:若 ./configure 报错缺少库,需在离线环境中提前准备好对应的 devel 包(如 pcre2-devel、zlib-devel、openssl-devel)并通过 rpm -ivh 或 dpkg -i 安装。
评论 (0)