Nginx 生产环境平滑升级指南:从二进制热部署到健康检查配置

在Nginx生产环境中实现不停机(平滑)升级版本的关键,是充分利用其支持热替换(Hot Replacement)的特性。以下是详细操作流程和注意事项:
一、关键原理
- 主进程:管理配置、绑定端口、控制子进程
- 工作进程:处理实际请求(
worker_processes) - 信号控制:
USR2:启动新版本二进制WINCH:优雅停止旧工作进程QUIT:完全退出旧主进程
二、详细操作步骤
1. 预检与备份
# 备份配置文件、二进制文件和日志
cp -r /usr/local/nginx /usr/local/nginx_backup_$(date +%F)
# 查看当前版本和编译参数
nginx -V2. 编译新版本(以这次静态编译为例)
# 下载新版源码
wget https://tengine.taobao.org/download/tengine-3.1.0.tar.gz
tar -xvf ./tengine-3.1.0.tar.gz
cd tengine-3.1.0
# 使用docker创建临时环境,这个退出docker时就会自动删除
docker run -it --rm -v $(pwd):/work alpine:latest sh
# 安装必要依赖
apk add --no-cache gcc g++ make perl linux-headers curl gnupg pcre-dev zlib-dev openssl-dev openssl-libs-static git
# 下载zlib依赖
wget https://zlib.net/zlib-1.3.1.tar.gz
tar xf zlib-1.3.1.tar.gz
# 设置编译参数,--prefix=/opt/nginx 表示默认运行目录为/opt/nginx,如tms
./configure --prefix=/opt/nginx --with-http_v2_module --with-http_ssl_module --add-module=./modules/ngx_http_upstream_check_module --with-cc-opt='-static-libgcc' --with-ld-opt='-static' --with-zlib=/work/tengine/zlib-1.3.1
# 也可以配置时保持与原版一致(注意输出参数)
# ./configure <原版参数> --with-http_stub_status_module...
# 四线程编译
make -j4
# 编译完的二进制在./objs/nginx3. 替换二进制文件(热部署)
# 替换二进制文件(不要make install!)
cp objs/nginx /usr/sbin/nginx4. 发送信号启动热更新
# 检测新版本是否正确(重要)
nginx -t
# 向旧主进程发送USR2信号(启动新实例)
kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid)
# 此时会生成新旧两个主进程PID文件:
# /usr/local/nginx/logs/nginx.pid # 新主进程
# /usr/local/nginx/logs/nginx.pid.oldbin # 旧主进程
5. 逐步关闭旧进程
# 发送WINCH信号让旧进程停止接受新连接,处理完现有请求后退出
kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid.oldbin)
# 观察旧进程状态(此时旧进程还在但不处理请求)
ps aux | grep nginx
6. 最终切换确认
# 如果新版本运行正常,彻底退出旧主进程
kill -QUIT $(cat /usr/local/nginx/logs/nginx.pid.oldbin)
# 如果发现问题需要回滚,立即发送HUP重启旧进程,TERM新进程:
kill -HUP $(cat /usr/local/nginx/logs/nginx.pid.oldbin)
kill -TERM $(cat /usr/local/nginx/logs/nginx.pid)
三、关键注意事项
编译参数一致性:
- 使用
nginx -V获取旧版本的编译参数,确保模块(如--with-http_ssl_module)和依赖库一致。
- 使用
验证环节:
- 升级前在生产环境的测试沙盒中验证:
nginx -t -c /usr/local/nginx/conf/nginx.conf
- 升级前在生产环境的测试沙盒中验证:
依赖项兼容性:
- 检查新版本是否依赖更高的OpenSSL、PCRE等库版本。
会话保持:
- 当使用长连接(如WebSocket)时,确保升级前通过配置
worker_shutdown_timeout合理超时。
- 当使用长连接(如WebSocket)时,确保升级前通过配置
回滚预案:
# 快速回滚方法 cp /usr/local/nginx/sbin/nginx_old /usr/local/nginx/sbin/nginx kill -USR2 <新主进程PID> # 启动旧版本监控指标:
- 升级后监控:
nginx -s status(需配置stub_status模块)- 系统负载、错误日志(
tail -f /usr/local/nginx/log/error.log)
- 升级后监控:
四、NGINX配置相关
本次升级配置修改部分主要是使用了 ngx_http_upstream_check_module模块,用来自动检查 upstream节点的可用性,配置文档可参考:https://tengine.taobao.org/document_cn/http_upstream_check_cn.html
- 添加自动替换参数,以
oms服务为例:
upstream omsserver{
server 172.16.3.134:8088 max_fails=30 weight=1;
server 172.16.3.134:8089 max_fails=30 weight=1; #上面这两行不动,添加下面三行
check interval=10000 rise=2 default_down=false fall=3 timeout=1000 type=http;
check_http_send "GET /kj/keepAlive HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}配置格式为:
Syntax: check
interval=milliseconds [fall=count] [rise=count] [timeout=milliseconds] [default_down=true|false] [type=tcp|http|ssl_hello|mysql|ajp] [port=check_port]
interval:向后端发送的健康检查包的间隔。
rise(rise_count): 如果连续成功次数达到rise_count,服务器就被认为是up。
default_down: 设定初始时服务器的状态,如果是true,就说明默认是down的,如果是false,就是up的。默认值是true,也就是一开始服务器认为是不可用,要等健康检查包达到一定成功次数以后才会被认为是健康的。
fall(fall_count): 如果连续失败次数达到fall_count,服务器就被认为是down。
timeout: 后端健康请求的超时时间。
type:健康检查包的类型,现在支持以下多种类型:
tcp:简单的tcp连接,如果连接成功,就说明后端正常。ssl_hello:发送一个初始的SSL hello包并接受服务器的SSL hello包。http:发送HTTP请求,通过后端的回复包的状态来判断后端是否存活。mysql: 向mysql服务器连接,通过接收服务器的greeting包来判断后端是否存活。ajp:向后端发送AJP协议的Cping包,通过接收Cpong包来判断后端是否存活。
我们使用的配置 check interval=10000 rise=2 default_down=false fall=3 timeout=1000 type=http; 含义为:每10s检测一次,如果连续两次都成功说明服务正常,nginx启动后默认所有节点都是成功的状态,连续测试失败三次表明服务不可用,检测检测请求超1s没响应就是失败。
check_http_send "GET /kj/keepAlive HTTP/1.0\r\n\r\n";和 check_http_expect_alive http_2xx http_3xx; 含义为使用 GET请求 /kj/keepAlive ,如果返回2xx和3xx状态码说明服务正常,一般情况下建议使用 HEAD请求,因为 HEAD 方法只请求服务器返回 HTTP 头部信息,而 不返回响应体 (body),对服务器没有压力,oms这个是使用 HEAD一直报错才换成 GET。
- 添加节点状态查看配置:
location /status {
auth_basic "Restricted Area";
auth_basic_user_file /usr/local/nginx/auth/htpasswd; #添加访问密码
check_status;
access_log off;
allow 10.0.0.0/8; #设置允许的网段,除了10.0.0.0/8和172.16.0.0/16其他都不允许访问
allow 172.16.0.0/16;
deny all;
}认证账号密码使用 htpasswd 命令创建,指定用户名后需要输入两次密码:
htpasswd -c ./htpasswd ks # 创建用户名为ks
可以使用 http://example.com/status 输入密码查看状态,同时支持不同的格式输出,默认是html格式:
/status?format=html
/status?format=csv
/status?format=json认证界面:

节点监控界面:

通过遵循上述步骤,可以在生产环境中实现Nginx版本的无缝升级,确保服务持续可用。


