负载均衡算法不是为了“看起来高级”,而是为了回答一个具体问题:这次请求应该交给哪一个后端实例处理?
1. 最朴素的轮询
轮询就是按顺序分配请求。
第 1 个请求 -> Server A
第 2 个请求 -> Server B
第 3 个请求 -> Server C
第 4 个请求 -> Server A优点:
- 简单。
- 容易理解。
- 适合后端机器配置差不多、请求耗时差不多的场景。
缺点:
- 不关心机器性能差异。
- 不关心当前连接数。
- 不关心某些请求特别重。
如果三台机器性能完全不同,普通轮询就可能不合理。
2. 加权轮询
加权轮询会给不同服务器设置不同权重。
Server A weight = 5
Server B weight = 3
Server C weight = 2大致意思是:A 分到更多请求,C 分到更少请求。
适合场景:
- 机器配置不同。
- 某些实例是新机器或弱机器。
- 想让部分实例承接更多流量。
加权轮询比普通轮询更贴近真实生产环境,因为真实机器很少完全一样。
3. 随机和加权随机
随机就是每次从可用实例中随机选一个。
加权随机是在随机时考虑权重,权重高的实例被选中的概率更大。
它的优点是实现简单,在请求量足够大时分布会比较均匀。
缺点是短时间内可能不够平滑,比如连续几次随机到同一台机器。
4. 最少连接数
最少连接数会优先选择当前连接数最少的实例。
Server A: 100 connections
Server B: 30 connections
Server C: 60 connections
新请求 -> Server B适合场景:
- 请求处理时间差异较大。
- 存在长连接。
- 不能只按请求数量判断负载。
比如 WebSocket、数据库代理、长轮询,这类场景中“连接数”比“请求数”更能反映压力。
5. 最短响应时间
最短响应时间会倾向于把请求分给响应更快的实例。
这听起来很聪明,但实现时要注意:
- 响应时间需要持续采样。
- 短时间抖动可能影响判断。
- 快的机器可能因为被分配太多请求而变慢。
所以它通常要配合平滑算法、窗口统计、异常值过滤使用。
6. 哈希算法
哈希算法会根据某个字段计算目标实例。
常见字段:
- 用户 ID。
- IP 地址。
- 请求路径。
- 某个业务 key。
比如:
hash(userId) % serverCount它的好处是同一个用户或同一个 key 可能落到同一台机器上。
适合场景:
- 需要会话保持。
- 本地缓存命中很重要。
- 同一个业务 key 希望固定路由到同一个实例。
问题是,如果服务器数量变化,普通哈希会导致大量 key 重新分布。
7. 一致性哈希
一致性哈希是为了解决普通哈希在扩容缩容时抖动太大的问题。
普通哈希:
hash(key) % serverCount一旦 serverCount 改变,大量 key 都会重新映射。
一致性哈希会把 key 和服务器都映射到一个环上,新增或删除节点时,只影响环上一小段数据。
它常见于:
- 分布式缓存。
- 分布式存储。
- 需要减少迁移成本的系统。
8. 算法不是孤立选择
实际系统里,负载均衡算法通常还会叠加这些机制:
- 健康检查:不健康的实例不参与分配。
- 权重调整:强机器多接流量,弱机器少接流量。
- 慢启动:新实例刚上线时先接少量流量。
- 熔断降级:失败率太高的实例暂时摘除。
- 超时重试:请求失败后按策略换实例重试。
所以算法只是基础,稳定性机制才决定它在生产里好不好用。
9. 怎么选算法
可以按场景粗略记:
| 场景 | 可考虑策略 |
|---|---|
| 机器配置相近,请求差异小 | 轮询 |
| 机器配置不同 | 加权轮询 / 加权随机 |
| 长连接较多 | 最少连接数 |
| 请求耗时差异明显 | 最少连接 / 最短响应时间 |
| 需要会话保持 | 哈希 |
| 扩缩容时希望迁移少 | 一致性哈希 |
10. 小结
负载均衡算法的核心不是背名字,而是理解它们观察的指标不同:
- 轮询看顺序。
- 加权看机器能力。
- 最少连接看当前连接压力。
- 最短响应时间看近期处理速度。
- 哈希看请求和实例之间的稳定映射。
- 一致性哈希看扩缩容时的迁移成本。
真正做架构设计时,算法只是第一层,还要继续考虑健康检查、故障摘除、限流、重试和可观测性。
留言板