Nginx加权轮询灰度发布核心是确保小比例流量真实、稳定、可回退地打到新版本;需满足三前提:后端地址可区分、定义upstream启用加权轮询、weight为正整数且只看相对大小。

用 Nginx 加权轮询做灰度发布,核心不是“设多少”,而是让小比例流量真实、稳定、可回退地打到新版本。重点在于配置结构合理、数值设计得当、运行状态可控。
必须先满足三个硬性前提
光写 weight=1 没用,流量不会自动对齐预期:
- 新旧服务地址必须可区分:不能共用同一 IP+端口,比如 v1 走 192.168.1.10:8080,v2 就得另起 192.168.1.11:8080;若用域名,也要确保 v1.example.com 和 v2.example.com 解析到不同后端
- 必须定义 upstream 块并启用加权轮询:不能直接 proxy_pass http://xxx,要先声明 upstream,再在其中写 server ... weight=
- weight 值必须是正整数,且只看相对大小:v1 weight=99 / v2 weight=1 和 v1 weight=199 / v2 weight=2 效果一样,都是 ≈1% 流量进 v2;避免小数、负数或 0
小权重怎么设才更准、更稳
想导 5% 流量给新版本,别直接写 weight=5 和 weight=95——大基数容易因连接复用、四舍五入、请求累积误差导致实际偏差放大:
- 推荐起步用小基数,比如 v1 weight=20,v2 weight=1(即 20:1),理论分流比仍是 ≈4.76%,但调度更灵敏、调整更平滑
- 上线前做热更新验证:改完配置执行 nginx -t && nginx -s reload,立刻用 curl 或日志观察是否真有请求落到 v2
- 给响应头加标识,比如在 v2 的 upstream server 行后加 proxy_set_header X-Version "v2",方便快速确认流量走向
让小权重真正“平滑”起来的关键动作
Nginx 默认 weighted round-robin 不保证请求序列均匀穿插(比如可能连发 20 次给 v1 再来 1 次给 v2),要减少瞬时倾斜,得靠配套机制:
- 开启健康检查:health_check interval=3 fails=2 passes=2,避免故障节点还持续收小权重流量
- 慎用 keepalive:长连接会复用上游连接,导致小权重节点在连接池中“被跳过”。如需高精度,可临时关掉 upstream 的 keepalive 或调小 keepalive_requests
- 预设回滚路径:把 v2 的权重从 1 改成 0 是无效的(Nginx 会跳过 weight=0 的节点),正确做法是保留该 server 行但注释掉,或提前准备两套 upstream 块,用 map 切换
验证与监控不能少
权重生效≠流量达标,得靠数据说话:
- 在 access_log 中加入 $upstream_addr 和 $upstream_http_x_version,实时看每条请求到底去了哪
- 用 Prometheus + nginx-vts-exporter 或自定义 log parser 统计各 upstream server 的请求占比,确认是否稳定落在目标区间(如 4.5%–5.5%)
- 灰度期间盯紧 v2 的错误率、P95 延迟、连接超时数,一旦异常飙升,立即调低 weight 或切走流量


















