Nginx采用平滑加权轮询算法动态分发流量,核心依赖currentWeight(实时积分)、effectiveWeight(带健康反馈的活权重)和totalWeight协同演进,每次请求独立计算选最优节点,不预生成序列。

Nginx 的流量分发不是靠“凑够几个请求再切服务器”实现的,而是用一套实时演进、带状态的数学机制——平滑加权轮询(Smooth Weighted Round-Robin),来动态决定每次该选哪台后端。理解它,关键在于抓住三个核心变量如何随每次请求协同变化。
currentWeight 是“实时积分”,决定当下选谁
每台服务器都维护一个 currentWeight 值,初始为 0。每次请求到来时,Nginx 会: - 给每台服务器的 currentWeight 加上它的 effectiveWeight(通常是配置的 weight) - 比较所有 currentWeight,选最大的那台 - 把选中服务器的 currentWeight 减去所有 effectiveWeight 的总和(totalWeight)这个过程不依赖历史序列,也不预生成列表,而是一步一步“算出来”的。比如权重为 {a:4, b:2, c:1},totalWeight=7,第一轮计算后 currentWeight 变为 {4,2,1} → 选 a → a 变成 4−7=−3;下一轮就变成 {1,4,2} → 选 b。整个过程天然避免了连续打爆某台机器。
effectiveWeight 是“可调节的权重刻度”
它默认等于配置的 weight,但会在运行时浮动: - 后端异常(如超时、失败)时,effectiveWeight 临时减 1 - 后续调用成功一次,就加 1,直到恢复到原始 weight - 这让 Nginx 能在不剔除节点的前提下,自动降低故障机的被选概率也就是说,effectiveWeight 不是静态配置值,而是带健康反馈的“活权重”。它参与每次 currentWeight 更新,直接影响调度走向。
选中的顺序是算法推导结果,不是人工排列
很多人误以为 Nginx 先生成一个类似 [a,b,a,c,a,b,a] 的固定序列再循环取值。其实不是——它没有预存序列,也没有缓存索引。每一次选择都是独立重算: - 所有节点 currentWeight 同步更新 - 仅比较当前值,无记忆式跳转 - 即使中间有节点临时失效,算法仍能自适应调整后续分布这也是为什么同样权重 {5,3,1},在不同时间点或不同故障状态下,实际请求序列可能略有差异,但长期统计比例严格趋近权重比,且短周期内也足够分散。
不复杂但容易忽略


















