加权轮询仅负责按权重分发请求,不提供限流与降级能力;需协同limit_req实现速率控制、max_fails/fail_timeout实现被动健康检查降级,并通过proxy_next_upstream支持5xx重试以达成软降级。

加权轮询本身不直接提供限流和降级能力,它只负责按权重分发请求。要实现“加权轮询 + 限流降级”的组合策略,需要在 Nginx 中分层配合其他模块协同工作:上游用 upstream 配置加权轮询,中层用 limit_req 做请求速率控制,底层靠健康检查与主动剔除机制支撑降级逻辑。
加权轮询是流量分发的“方向盘”,不是“刹车”或“离合器”
它决定“谁多接、谁少接”,但不管“接多少”或“接不住怎么办”。所以不能指望只写 weight=3 就能限流或自动降级。必须明确各模块职责:
-
加权轮询:在
upstream块中通过weight参数设置,影响长期请求分配比例 -
限流:靠
limit_req_zone和limit_req指令,在http或server块中定义每秒请求数、突发容量、拒绝行为 -
降级基础:依赖
max_fails+fail_timeout实现被动健康检查;故障节点自动摘除,流量自然转向其余加权节点
配置示例:三台后端,按能力加权,同时全局限流 + 单机熔断
假设后端服务地址为 192.168.1.10:8080(强)、192.168.1.11:8080(中)、192.168.1.12:8080(弱),希望:
- 长期请求比约为 3:2:1
- 整个 upstream 入口限速为 1000 req/s,允许最多 200 个突发请求
- 任一后端连续 3 次失败(如 50x)后,30 秒内不再转发请求给它
对应配置如下:
http {
# 定义限流区域:按 $binary_remote_addr(客户端IP)做粒度
limit_req_zone $binary_remote_addr zone=perip:10m rate=1000r/s burst=200 nodelay;
<pre class='brush:php;toolbar:false;'>upstream backend_pool {
# 加权轮询:总权重=6,A占50%,B占33%,C占17%
server 192.168.1.10:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=2 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 weight=1 max_fails=3 fail_timeout=30s;
}
server {
location /api/ {
# 启用限流
limit_req zone=perip;
# 反向代理到加权池
proxy_pass http://backend_pool;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
proxy_next_upstream_tries 2;
}
}}
关键协同点:让限流和降级“感知”加权结构
真正形成组合拳,要注意三个衔接细节:
- 限流放在 proxy_pass 前:保证所有入口请求先被统一节流,避免某台高权服务器因流量突增率先被打垮
- proxy_next_upstream 要启用 5xx 错误重试:当高权节点返回 503(例如自身已触发内部限流),Nginx 可按加权规则重试下一个可用节点,实现软降级
-
fail_timeout 时间需大于后端自身超时:比如后端设了
proxy_read_timeout 10s,那么fail_timeout至少设为 15s,防止因瞬时慢响应误判为宕机
进阶提示:用状态监控补足“动态降级”能力
Nginx 原生不支持根据 CPU 或响应时间动态调权。若需更智能的降级(比如某台机器响应 P95 > 2s 就临时降权),可:
- 用 OpenResty + Lua 获取 upstream 状态,结合
balancer_by_lua_block动态调整路由 - 接入 Prometheus + nginx-vts-exporter 监控各节点成功率、延迟,再由外部调度器(如 Consul Template)热更新 upstream 配置
- 对关键接口单独配置
limit_req,比如/pay/限得更严,而/status/完全放行,实现业务级降级优先级


















