平滑升级Nginx需只替换二进制、不重启、不中断服务:先用nginx -V提取prefix、conf-path及所有with-module参数,确认systemd兼容性;下载源码后严格复用参数configure并仅make,取objs/nginx替换旧二进制;再按USR2→WINCH→QUIT顺序发信号完成热切换,最后验证进程、版本与业务,并保留回滚能力。

平滑升级源码编译的 Nginx,核心是只换二进制、不动配置,全程不重启、不中断请求。关键在于复用旧参数编译新版本,并严格按信号顺序切换进程。
确认旧版编译参数和运行状态
这一步跳过,升级大概率失败。必须执行 nginx -V(大写 V),重点提取三类信息:
-
--prefix=:安装根路径,比如
/usr/local/nginx -
--conf-path=:配置文件实际位置,如
/usr/local/nginx/conf/nginx.conf -
所有 --with-xxx-module:比如
--with-http_ssl_module、--with-http_v2_module,缺一不可
同时检查启动方式:ps aux | grep nginx 看主进程命令是否含 systemd。如果是 systemd 管理,且 ExecStart 硬编码了二进制路径,USR2 信号会被拦截——需先改 service 文件或临时改用原生方式操作。
下载并精准编译新版二进制
从 nginx.org 下载目标版本(如 nginx-1.30.2.tar.gz),解压后进入目录:
- 粘贴旧版
nginx -V输出中的--configure arguments,完整执行./configure ...(路径和模块一个都不能少) - 只运行
make,**绝对不要**make install——它会覆盖 conf/、html/、logs/ 等目录,直接破坏现有配置和静态资源 - 新二进制仅存在于
objs/nginx,体积小、无副作用
安全替换并触发热切换
先备份再操作:
- 备份旧二进制:
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak - 覆盖新二进制:
cp objs/nginx /usr/local/nginx/sbin/ - 验证语法:
/usr/local/nginx/sbin/nginx -t必须返回success
然后按顺序发信号(PID 来自 /usr/local/nginx/logs/nginx.pid):
-
kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)→ 启动新 master + worker,此时新旧进程共存 -
kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid.oldbin)→ 只关停旧 worker(注意是.oldbin文件) -
kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)→ 旧 worker 全退出后,再关停旧 master
验证与回滚准备
升级完成后立刻检查:
- 进程:
ps aux | grep nginx应只剩新 master 和新 worker;nginx.pid.oldbin文件应已消失 - 版本:
nginx -v和nginx -V确认版本号和模块一致 - 业务:访问接口、查
access.log是否有新增记录、看error.log有无 502/段错误 - 回滚:若异常,立即
kill -HUP $(cat /usr/local/nginx/logs/nginx.pid)可重载旧二进制(前提是旧文件未被覆盖),或用备份的nginx.bak手动恢复











