加权轮询仅控制请求分发的初始比例,不感知实时负载;调优关键是让权重贴近节点真实服务能力,需做好健康检查、合理设置被动探测参数、开启连接复用,并借助lua或prometheus实现动态权重。

理解加权轮询在大促场景下的真实作用
加权轮询(Weighted Round Robin)本身不是高并发的“银弹”,它只是负载分发策略之一。大促期间真正影响吞吐和稳定性的,是后端节点的实际处理能力、健康状态、网络延迟以及请求特征(如长连接、大 Body、缓存命中率)。Nginx 的 upstream 模块中配置 weight,仅控制请求分发的**初始比例**,不感知实时负载。所以调优重点不是“怎么设权重”,而是“如何让权重贴近真实服务能力”。
基础配置必须做对的三件事
很多团队线上出问题,其实卡在基础项没配稳:
-
启用健康检查:用
health_check(需 stream 或 http 模块支持)或proxy_next_upstream+fail_timeout/max_fails组合,避免把流量打到已卡顿但 TCP 连接未断的节点上; -
关闭被动探测干扰:若用
max_fails=1 fail_timeout=10s,单次超时就摘除节点,大促时易误杀;建议设为max_fails=3 fail_timeout=30s,配合slow_start=60s防止新节点冷启动暴增压力; -
连接复用必须开:
proxy_http_version 1.1;+proxy_set_header Connection '';,否则每个请求建新连接,worker 进程 fd 和 TIME_WAIT 瞬间打满。
动态权重:用第三方模块补足 Nginx 原生短板
原生 Nginx 不支持根据 CPU、响应时间、队列长度等指标自动调权。生产环境推荐两种轻量方案:
-
lua-resty-upstream-healthcheck + lua-resty-balancer:在
balancer_by_lua_block中读取本地共享字典(shared dict)里由外部探针上报的各节点 RT/错误率,实时计算权重并调用set_current_peer; -
OpenResty + Prometheus + Alertmanager 反向控制:用 Prometheus 抓取各 upstream 节点指标,当某节点 95 分位响应时间 > 800ms 且持续 2 分钟,触发 webhook 调用 Nginx API(需启用
ngx_http_api_module)临时将其 weight 设为 0 或降为 1。
压测验证与上线灰度的关键检查点
大促前不做这三步,再好的配置也白搭:
-
用真实请求体压测:别只用 curl -I 或小 GET,要模拟用户上传图片、提交订单等带 body 和 cookie 的复合请求,观察 upstream 监控中各节点的
request_time分布是否与 weight 设置趋势一致; -
查 upstream 级别日志:开启
log_format upstream_log '... $upstream_addr $upstream_response_time $upstream_http_x_backend';,确认流量确实按预期比例落到不同 weight 节点,而非因 sticky session 或 cache key 导致倾斜; -
灰度阶段人工干预开关:在 upstream 块外定义
map $arg_wmode $dynamic_weight { default 1; "hot" 10; },通过 URL 参数临时提升某集群权重,便于突发流量时秒级切流。
不复杂但容易忽略的细节
weight 值本身无单位,只看相对大小。设 server a:8080 weight=10; 和 server b:8080 weight=100; 效果等同于 1 和 10。大促期间建议统一归一化到 1–10 区间,避免后期维护误解。另外,weight 不影响 keepalive 连接复用目标——复用只认 server 地址+端口,和 weight 无关。如果后端是异构集群(比如 Java 应用和 Go 应用混部),务必分开 upstream 块定义,不要靠 weight “硬扛”语言层性能差异。











