Dubbo 支持哪些负载均衡策略?
一则或许对你有用的小广告
欢迎加入小哈的星球,你将获得:专属的实战项目(4个项目都能学) / 1v1 提问 / 简历修改 / Java 学习路线 / 社群讨论 / 学习打卡 / 每月赠书
《Spring AI 项目实战(问答机器人、RAG 智能客服、联网搜索)》已完结,基于
Spring AI + Spring Boot 3.x + JDK 21...,查看介绍《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...,查看介绍;演示链接:http://116.62.199.48:7070/《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接:http://116.62.199.48/
新开坑项目:《从零手撸:秒杀系统高并发优化实战》 正在更新中...,查看介绍
截止目前,星球内专栏累计输出 150w+ 字,讲解图 5110+ 张,还在持续爆肝中.. 后续还会上新更多项目,已有 4700+ 小伙伴加入学习,欢迎点击围观
面试考察点
- 基础掌握度:面试官不仅仅是想知道你能背出几种策略的名字,更是想看你能否说清楚每种策略的核心思想和实现原理。
- 场景选型能力:不同业务场景该用哪种策略?如果你只能说 "默认的就行",那面试官基本就判定你对这块没有深入思考。
- 原理理解深度:加权轮询的权重是怎么计算的?一致性哈希的虚拟节点是干嘛的?能聊到这个层次,面试官才会觉得你是真懂,而不是背了个八股文。
核心答案
Dubbo 内置了 5 种 负载均衡策略,全部实现了 LoadBalance 接口:
| 策略 | 类名 | 核心思想 | 默认策略 |
|---|---|---|---|
| 随机 | RandomLoadBalance |
加权随机算法,按权重设置随机概率 | ✅ 是 |
| 轮询 | RoundRobinLoadBalance |
加权轮询,按权重逐一轮询,平滑调度 | ❌ |
| 最少活跃调用数 | LeastActiveLoadBalance |
优先将请求分配给活跃数最少的 Provider | ❌ |
| 一致性哈希 | ConsistentHashLoadBalance |
相同参数的请求路由到同一个 Provider | ❌ |
| 最短响应时间 | ShortestResponseLoadBalance |
优先分配给响应时间最短的 Provider(Dubbo 2.7+) | ❌ |
默认使用的是 加权随机(Random)。下面逐个拆解。
深度解析
一、RandomLoadBalance —— 加权随机
这是 Dubbo 的默认策略,别看名字叫 "随机",其实背后有一套加权机制。
原理:假设有 A、B、C 三个 Provider,权重分别是 5、3、2。那么总权重是 10,A 被选中的概率是 50%,B 是 30%,C 是 20%。具体做法是在 [0, 10) 范围内生成一个随机数,落在哪个区间就选哪个。
- 权重区间划分:将所有 Provider 的权重累加得到总权重,每个 Provider 占据一段连续的区间。比如 A 占
[0, 5),B 占[5, 8),C 占[8, 10) - 随机数命中:在
[0, 总权重)范围内生成随机数,看它落在哪个 Provider 的区间就选谁 - 特殊处理:如果所有 Provider 权重相同,则退化为普通随机,直接从列表里随机取一个,省去权重计算的开销
这个策略适合大多数通用场景,简单高效,调用量越大,请求分布越均匀。
二、RoundRobinLoadBalance —— 加权轮询
轮询大家好理解,就是 A、B、C 轮着来。但 Dubbo 用的是 Smooth Weighted Round-Robin(平滑加权轮询),这个跟 Nginx 的做法一样,很经典。
- 核心思路:每个 Provider 维护一个
currentWeight,每次请求先加上自身配置的weight,选currentWeight最大的那个提供服务,然后被选中的 Provider 的currentWeight减去总权重 - 为什么叫 "平滑":对比朴素轮询,如果 A=5、B=1、C=1,朴素做法会连续 5 次都打给 A,然后再给 B、C 各一次,这会导致 A 瞬间压力暴增。平滑轮询则把请求均匀打散了
- 适用场景:需要严格控制流量分配比例的场景,比如灰度发布时给新版本 10% 的流量
注意:早期版本的
RoundRobin在权重差异大的时候可能会有请求堆积问题,Dubbo 后续版本做了优化,加了预热和权重衰减机制。
三、LeastActiveLoadBalance —— 最少活跃调用数
这个策略的思路很直觉:谁最闲就找谁干活。
- 活跃数的含义:就是某个 Provider 正在处理但还没返回的请求数量。活跃数越少,说明这个节点要么处理速度很快,要么当前没什么压力
- 相同活跃数怎么办:退化为加权随机,在活跃数相同的 Provider 里按权重随机选一个
- 适用场景:Provider 处理能力差异较大的场景。比如有的机器是 8 核 16G,有的是 4 核 8G,用这个策略可以让能力强的机器多承担一些
四、ConsistentHashLoadBalance —— 一致性哈希
一致性哈希是分布式系统里的经典算法,Dubbo 用它来保证 "相同参数的请求总是打到同一个 Provider"。
- 哈希环:把
0 ~ 2^32-1的整数空间首尾相连成一个环,每个 Provider 通过哈希映射到环上的某个位置 - 虚拟节点:默认每个真实 Provider 有 160 个虚拟节点。为啥要这么多?因为如果只有 1 个节点,很容易出现数据倾斜——大部分请求都集中打到某几个 Provider 上。虚拟节点越多,分布越均匀
- 默认参数:用方法的第一个参数做哈希。可以通过
hash.arguments配置参与哈希的参数索引,用hash.nodes配置虚拟节点数 - 适用场景:有状态服务。比如某个用户的请求应该固定打到某一台机器上(那台机器上有这个用户的缓存数据)
五、ShortestResponseLoadBalance —— 最短响应时间
这是 Dubbo 2.7 之后新增的策略,思路也很直观:谁的响应最快就找谁。
- 原理:统计每个 Provider 最近一段时间的平均响应时间,优先把请求发给响应最快的那个。如果有多个 Provider 响应时间相同,再退化为加权随机
- 适用场景:对延迟敏感的业务。比如一些实时性要求高的接口,希望每次都打到最快的节点上
不过这个策略在实际生产中用得相对少一些,因为 "响应时间最短" 不代表 "最应该选它"——可能只是因为它最近还没怎么接到请求。
六、配置方式
Dubbo 支持在多个层面配置负载均衡策略,粒度从粗到细:
<!-- 1. 全局配置:对所有服务生效 -->
<dubbo:consumer loadbalance="random"/>
<!-- 2. 服务级别:对某个服务生效 -->
<dubbo:reference interface="com.example.UserService" loadbalance="leastactive"/>
<!-- 3. 方法级别:对某个方法生效(粒度最细) -->
<dubbo:reference interface="com.example.UserService">
<dubbo:method name="getUser" loadbalance="consistenthash"/>
</dubbo:reference>
也可以在 Provider 端配置:
<!-- Provider 端也能配,会作为默认值推荐给 Consumer -->
<dubbo:service interface="com.example.UserService" loadbalance="roundrobin"/>
优先级:方法级 > 服务级 > 全局,Consumer 端 > Provider 端。
七、策略选型建议
| 场景 | 推荐策略 | 原因 |
|---|---|---|
| 通用业务,无特殊需求 | random(默认) |
简单高效,调用量大时分布均匀 |
| 机器配置差异大 | leastactive |
让能力强的机器多干活 |
| 灰度发布 / 流量比例控制 | roundrobin |
精确控制流量分配比例 |
| 有状态服务 / 需要会话保持 | consistenthash |
相同参数的请求固定打到同一台 |
| 对延迟极度敏感 | shortestresponse |
优先选最快的节点 |
面试高频追问
-
Dubbo 默认的负载均衡策略是什么?能改吗?
- 默认是
Random(加权随机)。可以改,支持全局、服务级、方法级三个粒度配置。
- 默认是
-
一致性哈希中,如果某个 Provider 挂了,请求会怎样?
- 请求会顺时针找到下一个存活的 Provider,不会影响整体可用性。只影响挂掉节点对应的那些请求,其他请求的映射关系不变——这也是一致性哈希 "一致性" 的体现。
-
权重是怎么设置的?
- 可以在 Provider 端通过
dubbo:provider的weight属性设置,也可以通过运维工具(Dubbo Admin)动态调整权重,实现灰度发布或流量调度。
- 可以在 Provider 端通过
-
如果你的服务既有读操作又有写操作,负载均衡策略该怎么选?
- 读操作可以用
random或leastactive;写操作如果涉及状态(比如写到本地缓存),可以考虑consistenthash,让同一个实体的写请求固定打到一台机器上,避免数据不一致。
- 读操作可以用
常见面试变体
- "Dubbo 的
Random负载均衡是怎么实现加权的?" - "一致性哈希在 Dubbo 中是怎么用的?虚拟节点的作用是什么?"
- "Dubbo 的负载均衡策略可以在哪些层面配置?优先级是什么?"
记忆口诀
5 种策略:随机(默认)、轮询、最少活跃、一致性哈希、最短响应。
选型口诀:通用选随机,差异选活跃,灰度选轮询,有状态选哈希,低延迟选最短。
总结
Dubbo 内置 5 种负载均衡策略,默认用加权随机。面试时不光要能说出名字,更要能讲清楚每种策略的原理和适用场景。最容易加分的地方是结合生产经验谈选型——比如灰度发布用轮询、机器差异大用最少活跃数、有状态服务用一致性哈希,这些才是面试官真正想听到的。
