Nginx 通过 upstream 动态权重、健康检查、map 变量路由及热重载机制实现平滑流量切换:权重调整控制新连接分发,健康检查保障节点可用,map 实现无需 reload 的运行时路由,reload 保证旧连接不受影响。

在 Nginx 中,proxy_pass 本身不直接提供“平滑流量切换”能力,但结合 upstream 模块、健康检查、权重调整与热重载机制,可以构建出生产可用的平滑流量切换方案。
基于 upstream 的动态权重切换
将后端服务定义为 upstream 组,通过修改各 server 的 weight 值控制流量比例。Nginx reload 后新请求按新权重分发,已有连接不受影响,实现渐进式切流。
- 初始配置:两个后端,权重比为 100:0(全量指向旧版本)
- 切换时:逐步调高新版本 weight(如 80:20 → 50:50 → 0:100),每次仅改配置 +
nginx -s reload - 注意:weight 变更仅影响新连接;长连接、keepalive 连接会自然衰减,无需中断
配合健康检查自动摘除异常节点
使用 health_check(商业版)或开源模块如 nginx_upstream_check_module,可实时探测后端状态。当新版本就绪后,先将其加入 upstream 并启用健康检查;待探测成功后再提升权重,避免将流量导向未就绪实例。
- 健康检查路径建议用轻量接口(如
/healthz),返回 200 即视为存活 - 失败重试次数和间隔需合理设置(如
fall=3 rise=2 interval=2),防止误判抖动 - 配合
max_fails和fail_timeout实现自动屏蔽故障节点
利用变量 + map 实现运行时路由决策
借助 map 指令定义切换开关,配合 proxy_pass 动态指向不同 upstream。无需 reload 即可生效,适合灰度发布或紧急回滚。
- 定义一个开关变量(如来自请求头
$http_x_release_flag或 cookie) - 用 map 映射到 upstream 名称:
map $http_x_release_flag $backend { "v2" "backend_v2"; default "backend_v1"; } - proxy_pass 指向
http://$backend,Nginx 会在每次请求时解析变量并选择对应 upstream - 该方式要求所有 upstream 已预定义,且变量值稳定可预期
配合 systemd 或进程管理器实现无中断 reload
确保 nginx -s reload 执行时旧 worker 进程处理完存量请求再退出,新 worker 接管新连接。这是平滑切换的底层保障。
- 检查
worker_shutdown_timeout(1.19.1+)是否设置,控制旧 worker 最大等待时间 - 避免在 reload 前暴力 kill -9,应始终使用
nginx -s reload或systemctl reload nginx - 可通过
nginx -t验证配置语法,减少 reload 失败风险
不复杂但容易忽略的是:真正的“平滑”依赖于上游服务自身的优雅关闭能力。Nginx 只负责不中断新连接分发,后端需支持 graceful shutdown,才能让正在处理的请求完成后再退出。


















