Nginx实现平滑滚动发布需构建“健康节点识别+按需调度+旧连接容忍”机制:启用主动健康检查或DNS动态解析,配合后端优雅上下线,并通过upstream_conf、error.log及socket连接数验证效果。

要让 Nginx 在后端集群升级时支持平滑滚动发布,关键不是改 proxy_pass 一行,而是构建一套“自动识别健康节点 + 按需调度流量 + 容忍旧连接”的协同机制。Nginx 本身不主动发现服务变化,必须靠外部配合或模块增强。
启用主动健康检查(推荐方案)
原生开源版需打 nginx_upstream_check_module 补丁;若用 Nginx Plus 可直接启用。配置后,Nginx 每隔几秒探测后端 /health 接口,失败达阈值即标记为 down:
- 节点被标记为 down 后,不再接收新请求,但已有长连接(如 WebSocket、keep-alive 请求)继续处理完毕
- 新实例启动并返回 200 健康响应后,自动加入 upstream,开始分担流量
- 滚动发布时,每次只下线一个实例,Nginx 自动跳过它,其余节点照常服务
使用 DNS 动态解析(轻量无侵入)
适合与 CoreDNS、Consul 或 Kubernetes Service 配合。Nginx 不直写 IP,而是通过变量解析域名:
- 配置 resolver 并设置短 TTL(例如 valid=5s),确保 DNS 缓存快速更新
- upstream 中只定义一个域名条目,proxy_pass 必须用变量形式(如
set $srv "api.internal:8080"; proxy_pass http://$srv;),否则 DNS 不会刷新 - 发布时,先让新实例注册进 DNS,再逐步剔除旧 IP;Nginx 在下次解析时自然切换到新地址池
配合后端优雅上下线策略
Nginx 的健康检查只是“开关”,真正平滑依赖后端行为配合:
- 新实例启动后,先等待 /health 返回 200,再开放注册,避免流量打到未就绪服务
- 旧实例收到 SIGTERM 后,应停止 accept 新连接,但保持运行直到所有活跃请求完成(建议设
proxy_read_timeout 60以上) - 在 upstream 中合理设置
max_fails=3 fail_timeout=30s,避免短暂抖动误判下线
验证与可观测要点
上线后不能只看页面是否打开,要确认机制真实生效:
- 执行
curl -I http://your-nginx/upstream_conf?upstream=backend(需启用 stub_status 或 upstream_conf 模块)查看各节点状态 - 观察 error.log 是否有大量
no live upstreams或connect() failed,说明健康检查失效或后端未就绪 - 用
ss -tn | grep :8080查看旧实例的 socket 连接数是否缓慢归零,验证优雅退出是否完成


















