Nginx默认轮询实为平滑加权轮询(SWRR),通过动态维护current_weight、effective_weight和weight三变量实现请求均匀分散;未配weight时各节点权重为1,配置weight后自动启用SWRR,避免传统加权的请求“扎堆”,并支持健康检查联动。

Nginx 的轮询算法不是简单地按顺序轮流分发请求,而是通过“平滑加权轮询”(Smooth Weighted Round-Robin)实现服务请求的均匀、稳定、可预期的转发。它既满足权重比例要求,又避免高权重节点被连续集中调用,从而真正实现负载的平滑分摊。
默认轮询与加权轮询的区别
未显式配置时,Nginx 使用基础轮询(Round Robin),即按顺序循环选择后端节点,各节点权重默认为 1,请求均分。一旦配置了 weight 参数,就启用加权轮询;但早期简单加权方式存在“扎堆”问题——比如权重 {5,1,1} 可能产生序列 a,a,a,a,a,b,c,导致 a 节点瞬时压力过大。
- 基础轮询:纯顺序循环,无状态,适合能力一致的后端
- 传统加权轮询:按权重重复排列后轮询,易造成请求堆积
- 平滑加权轮询:动态维护每个节点的当前权重(
current_weight),每次选最大值并重置,天然规避连续调度
平滑加权轮询的核心逻辑
算法不依赖历史轮次计数,仅靠三个变量实时决策:
-
weight:配置中声明的静态权重,如
server 192.168.1.10 weight=4; - effective_weight:运行时有效权重,节点异常时临时下调(如失败一次减 1),恢复成功后逐步回升,保障容错性
- current_weight:每轮参与比较的动态值,初始为 0,每次累加自身 effective_weight,选中后减去全部 effective_weight 总和
例如权重 {a:4, b:2, c:1},总 effective_weight = 7。第 1 轮:{0,0,0} → {4,2,1} → 选 a → {−3,2,1};第 2 轮:{−3,2,1} + {4,2,1} = {1,4,2} → 选 b → {1,−3,2}……最终生成序列 a,b,a,c,a,b,a,5 次 a 分散在 7 次请求中。
配置与实际效果验证
在 upstream 块中设置即可启用:
upstream backend {
server 192.168.1.10 weight=4;
server 192.168.1.11 weight=2;
server 192.168.1.12 weight=1;
}
无需额外指令,默认生效。可通过 stub_status 或日志统计验证实际分发比例:连续发送 700 次请求,a 应接近 400 次,b 接近 200 次,c 接近 100 次,且相邻相同节点出现间隔明显拉长。
与其他策略的协同使用
平滑加权轮询可与健康检查机制联动:
- 节点失败时,
effective_weight自动衰减,current_weight增速变慢,被选中的概率下降 - 配合
max_fails和fail_timeout,故障节点会被临时屏蔽,不参与 current_weight 计算 - 与
least_conn不兼容——后者基于活跃连接数,属于另一类调度维度
它专注在“请求频次”维度做权重公平分配,是 Nginx 在高并发场景下兼顾性能、稳定与可预测性的关键设计。


















