nginx 默认不支持基于请求频率的动态负载均衡,因其设计为轻量、异步、无状态,仅支持轮询、least_conn等静态或连接/响应时间相关算法,无法实时统计并调整各后端qps。

Nginx 本身不直接支持“基于请求频率”(如单位时间内请求数最多者优先少分、最少者多分)的动态负载均衡算法。它没有内置的实时统计并据此反向调整流量的机制。但可以通过组合配置与外部手段,间接实现按请求频率感知的流量调节效果。
为什么 Nginx 默认不支持“按请求频率”调度
Nginx 的核心设计是轻量、异步、无状态。它的负载均衡算法(轮询、加权轮询、least_conn、ip_hash、least_time)均基于:
- 静态权重(配置时写死)
- 连接数(least_conn)
- 响应时间(least_time,仅 Plus 版本)
- 客户端标识(ip_hash)
它不记录或统计每台后端在最近 1 秒/10 秒内的实际请求数,因此无法原生做“谁当前 QPS 低就多导流”。
接近“按请求频率”分发的可行方案
✅ 利用 least_conn(最少连接数)近似高频/低频场景
适用于长连接(如 WebSocket、HTTP/2 流式响应)或请求处理时长差异大的服务:
- 连接数少 → 往往意味着当前负载较轻、处理能力空闲
- Nginx 每次选 server 时挑当前活跃连接最少的那个
upstream backend {
least_conn;
server 192.168.1.10:8001;
server 192.168.1.11:8001;
}
⚠️ 注意:对短连接(典型 HTTP/1.1)、秒级完成的 API,least_conn 效果有限——连接建立/断开太快,统计失真。
✅ 启用并依赖 least_time(仅 Nginx Plus)
Nginx Plus 提供 least_time 指令,基于后端平均响应时间 + 活跃连接数综合打分,本质是倾向选择“响应快 + 不忙”的节点:
upstream backend {
least_time last_byte fail=3 timeout=1s;
server 192.168.1.10:8001;
server 192.168.1.11:8001;
}
-
fail=3:连续失败 3 次标记不可用 -
timeout=1s:健康检查超时阈值 - 它会动态学习后端性能,响应越快、越稳定,获得请求越多 → 间接反映“处理能力强 → 可承受更高请求频率”
✅ 主动健康检查 + 动态权重(需脚本辅助)
虽然 Nginx 开源版不支持运行时改权重,但可通过以下方式模拟“按频控流”:
- 后端暴露
/health?qps接口,返回当前 30 秒平均 QPS(如{"qps": 42}) - 外部监控脚本(如 Python + cron)定期调用该接口
- 若某台 QPS 超过阈值(如 > 100),则自动降低其 weight(修改 nginx.conf 或 upstream 文件)
- 执行
nginx -s reload生效
示例上游配置(配合脚本动态调整):
upstream backend {
server 192.168.1.10:8001 weight=5; # 默认权重
server 192.168.1.11:8001 weight=5;
}
? 实际中,这种方式运维成本较高,适合对稳定性要求极高、且有配套运维平台的场景。
✅ 基于 URL 或 Header 的静态分流(规避高频路径)
若某些路径天然高并发(如 /api/v1/order/pay),可提前拆离:
location ^~ /api/v1/order/pay {
proxy_pass http://pay_backend;
}
location /api/ {
proxy_pass http://general_backend;
}
再为 pay_backend 单独配置更强机器或更高权重,相当于按业务请求频率特征预分配资源。
不推荐的做法
- 尝试用 Lua + OpenResty 实时统计 QPS 并改 upstream —— 易引发锁竞争、状态不同步、reload 风险,复杂度远超收益。
- 依赖
$request_time变量做 if 判断路由 —— Nginx 不允许在 upstream 或 proxy_pass 中使用运行时变量做条件路由。
不复杂但容易忽略











