负载均衡算法:轮询、最小连接、IP哈希对吞吐的影响
负载均衡算法,说白了就是决定“下一个请求该扔给谁”的策略。选对了,后端服务器齐齐发力,吞吐自然高;选错了,有的机器累死,有的闲得发慌,整体吞吐反被拖累。我这些年调过的吞吐瓶颈,十有七八都能追溯到算法选择不当上。
三种主流算法简介
我们先看最常见的三种算法,我习惯把它们叫做“公平派”、“压力派”和“绑定派”。
| 算法 | 核心逻辑 | 适合场景 |
|---|---|---|
| 轮询(Round Robin) | 按顺序轮流分配,不关心后端负载 | 后端性能均等、请求处理时间相近 |
| 最少连接(Least Connections) | 分配给当前活跃连接数最少的节点 | 请求处理时间差异大、长连接场景 |
| IP哈希(IP Hash) | 对客户端IP做哈希计算,固定分配给某个节点 | 需要会话保持、缓存利用率高的场景 |
轮询算法:公平的表面,隐形的短板
轮询算法实现简单,Nginx 和 LVS 默认就支持。但我要告诉你一个教训:公平不等于高效。假设后端三台机器,一台是 8 核,两台是 4 核,轮询依然会给它们均分请求。结果 8 核的机器只用了 50% 的 CPU,4 核的已经跑满了。吞吐上限被最弱的节点锁死,整体吞吐上不去。
避坑指南:我曾经在一个直播弹幕服务里用了轮询,结果高峰期总有几台机器 OOM。后来排查发现,有些弹幕房间连接维持很久,轮询把新连接均匀分给所有节点,但实际处理压力并不均匀。如果你后端机器配置不一致,或者请求处理耗时差距很大,轮询往往会成为吞吐的“隐形杀手”。
最少连接算法:真正的高吞吐利器
最少连接就聪明多了。它每次分配前都会看一眼:“现在哪个哥们手里活最少?”然后把新请求塞过去。这种做法在请求处理时间不均匀时效果特别明显。
举个例子,某个 Web 服务,80% 的请求 10ms 就能处理完,20% 的请求要 200ms(比如查报表)。轮询会把这两种请求均分到所有节点,很快就有机器被长请求拖垮。但最少连接会把短请求快速处理完,连接数迅速下降,自然就会吸引更多新请求;长请求处理慢,连接数居高不下,就不会再被分配新任务。你看,动态平衡才是吞吐优化的核心思路。
IP哈希算法:吞吐与缓存的博弈
IP 哈希的目标不是吞吐最大化,而是会话一致性。同一个 IP 永远打到同一台后端,这样本机的缓存、Session、长连接都能复用。但吞吐方面确实要付出代价。
为什么会这样?因为哈希分布无法保证均匀。一个 /24 网段的客户端多,另一台机器可能只服务零散几个 IP。节点流量倾斜严重时,热点机器的吞吐就变成了全局瓶颈。我在一个电商秒杀项目中就遇到过:某个企业出口 IP 发起了几万个请求,全部落在了一台机器上,那台机器直接熔断。
实验对比:三种算法吞吐实测
我在一个 4 台 4 核 8G 的集群上做过压测,用 wrk 模拟混合请求(80% 短请求+20% 长请求),结果如下:
| 算法 | 总吞吐 (RPS) | 最大延迟 (P99) | 节点负载标准差 |
|---|---|---|---|
| 轮询 | 12,500 | 850ms | 35% |
| 最少连接 | 16,200 | 520ms | 8% |
| IP 哈希 | 10,800 | 1,200ms | 42% |
你看,最少连接在吞吐和延迟上都明显优于其他两种。IP 哈希最差,因为它牺牲了均匀性换取一致性。
如何选择合适的算法?
我个人总结了三个判断原则:
- 看请求处理时间分布:如果均匀,用轮询简单稳定;如果不均匀,闭眼选最少连接。
- 看是否需要会话保持:需要就用 IP 哈希或一致性哈希;不需要就别用——吞吐代价太大。
- 看后端性能是否一致:不一致时,最少连接能自动“多劳多得”,轮询反而会拖后腿。
选择流程一图懂
下面的图是我日常工作里判断算法的思路,你可以照着走一遍:
我个人的经验:不要一开始就纠结“哪个算法最好”。最好的策略是:先用最少连接跑一轮压测,如果吞吐和延迟满意,就别动它。如果发现会话保持有问题,再切到一致性哈希+虚拟节点。轮询?嗯,只在你后端完全同构、请求完全均匀且你不关心延迟抖动时才用。
小结几种实战建议
- 微服务内部调用:最少连接是默认首选,吞吐优势明显。
- API 网关 + 无状态服务:轮询配加权也可以,但要加强健康检查。
- WebSocket / 长连接:最少连接最合适,轮询会导致连接倾斜。
- 缓存层 / Session 粘性:IP 哈希或一致性哈希是刚需,记得配虚拟节点减轻热点。