Dubbo 支持哪些负载均衡策略?

#中间件#面试八股

Dubbo 支持哪些负载均衡策略?

结论先行:Dubbo 内置五种——随机(Random)、轮询(RoundRobin)、最小活跃数(LeastActive)、最短响应(ShortestResponse)、一致性哈希(ConsistentHash),另有 P2C(Power of Two Choices)。默认随机加权,权重来自提供者配置或运行时动态调整。

一、五种策略速查

策略名字核心逻辑适用场景风险
加权随机random按权重区间取随机数通用默认短时间可能重复打同一台
加权轮询roundrobin平滑加权轮询,按序分配实例性能接近、需要均摊慢实例会积压请求
最小活跃leastactive选活跃调用数最小的,相同则随机处理耗时差异大需维护计数器,有统计滞后
最短响应shortestresponse按成功调用平均耗时加权长尾明显的场景样本少时抖动大
一致性哈希consistenthash参数哈希 → 环 → 顺时针找节点需要同一参数落到同一台(缓存)节点变更需虚拟节点摊平
P2Cp2c随机取两个,选活跃数小的大规模集群需要足够实例数

二、平滑加权轮询为什么“平滑”

朴素轮询会把权重 5 的节点前五个请求全给它,造成瞬时尖峰。Dubbo 的平滑版本给每个节点维护 currentWeight,每轮加上静态权重、选中最大者、再把该节点减去总权重:

权重 A=5, B=1, C=1(总权重 7)

轮次  currentWeight       选中
 1    A5 B1 C1            A → A:-2
 2    A3 B2 C2            A → A:-4
 3    A1 B3 C3            B → B:-4
 4    A6 B-3 C4           A → A:-1
 5    A4 B-2 C5           C → C:-2
 6    A9 B-1 C-1          A → A:2
 7    A7 B0 C0            A

七轮里 A 出现 5 次、B 与 C 各 1 次,且分布均匀,不会出现连续五次打 A。

三、配置方式

全局:

dubbo:
  consumer:
    loadbalance: roundrobin

方法级与权重:

@DubboReference(loadbalance = "leastactive")
private ReportService reportService;
// 提供者启动时声明权重,越大分到的流量越多
@DubboService(weight = 200)
public class ReportServiceImpl implements ReportService { }

一致性哈希还可以指定参与哈希的参数下标,避免把 userId 之外的参数也算进去:

// parameters 是键值成对出现的字符串数组
@DubboReference(
        loadbalance = "consistenthash",
        parameters = {"hash.arguments", "0", "hash.nodes", "160"})
private CacheService cacheService;

四、动态权重与预热

新实例刚启动时 JIT 未预热、缓存未填充,直接按权重接流会被打慢。Dubbo 提供预热机制:实例启动后权重从 1 逐步涨到配置值(默认预热 10 分钟),由 warmup 参数控制。

常见追问

  • 追问:最小活跃数为什么需要“相同则随机”?活跃数相同说明负载接近,随机可以避免所有请求挤向同一个下标。
  • 追问:一致性哈希的虚拟节点有什么用?真实节点少时哈希环分布不均,每个真实节点映射 160 个虚拟节点可以把倾斜控制在可接受范围。
  • 追问:生产上怎么选?多数服务用默认 random;有本地缓存需求的用 consistenthash;耗时差异大的用 leastactive;发现长尾明显再考虑 shortestresponse。

小结

  • 五种内置策略 + P2C,默认加权随机。
  • 平滑加权轮询通过 currentWeight 抵消瞬时尖峰。
  • 权重可静态配置,也可运行时按活跃数动态调整,并有预热保护。
  • 选型依据是“实例是否同质”和“是否存在长尾”,不是性能高低。
笔记加载中…