源码编译安装的Nginx支持真正平滑升级:不中断服务、不丢请求、不断开连接,关键在于复用旧版编译参数、仅替换二进制文件,并严格按USR2→WINCH→QUIT信号顺序控制新旧进程切换。

源码编译安装的 Nginx 支持真正的平滑升级:不中断服务、不丢请求、不断开已有连接。关键在于复用旧版编译参数、只替换二进制文件、并严格按信号顺序控制进程生命周期。
确认旧版本编译参数和运行状态
这一步不能跳过,否则新进程大概率启动失败。
- 执行 nginx -V(大写 V),重点记录:
— --prefix=(安装根路径,如/usr/local/nginx)
— --conf-path=(配置文件位置)
— 所有 --with-xxx-module(比如--with-http_ssl_module、--with-http_v2_module) - 检查是否由 systemd 管理:
ps aux | grep nginx,若主进程命令行含systemd,则 kill 信号可能被拦截,需改用绝对路径启动或调整 service 文件 - 确认 PID 文件位置(通常是
/usr/local/nginx/logs/nginx.pid或/run/nginx.pid)
下载并编译新版 Nginx(不 install)
新版必须使用与旧版完全一致的 configure 参数(可新增模块,但不能漏掉旧模块)。
- 从 nginx.org 下载目标版本源码包,解压后进入目录
- 粘贴旧版
nginx -V中的--configure arguments,执行:./configure --prefix=/usr/local/nginx --with-http_ssl_module ... - 运行 make(不是
make install)——新二进制仅生成在objs/nginx - 备份旧二进制:
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
替换二进制并发送控制信号
替换后靠信号触发新旧进程切换,三步顺序不可颠倒:
- 覆盖二进制:
cp -f objs/nginx /usr/local/nginx/sbin/nginx - 语法检查(必须成功):
/usr/local/nginx/sbin/nginx -t - 发 USR2 启动新 master + 新 worker:
kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)
→ 此时ps aux | grep nginx应看到两组进程(旧 master + 新 master) - 等几秒后,发 WINCH 关旧 worker(注意 PID 文件是
.oldbin):kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid.oldbin)
→ 旧 worker 开始优雅退出,处理完当前请求后关闭 - 确认旧 worker 全退(
ps中不再出现旧 worker)后,发 QUIT 终止旧 master:kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)
验证与回滚准备
升级完成不等于万事大吉,必须验证功能与稳定性。
- 检查进程:只剩一组 master + worker,且 PID 已更新到
nginx.pid,.oldbin文件应消失 - 确认版本:
/usr/local/nginx/sbin/nginx -V查看是否为新版本、模块是否齐全 - 访问业务接口,观察 access.log 和 error.log,排查 502/503、连接重置等异常
- 保留
nginx.bak和配置备份,若异常可快速回滚:
还原二进制 +kill -HUP $(cat nginx.pid)(重载)或直接重启


















