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+ 小伙伴加入学习,欢迎点击围观

面试考察点

  1. 基础掌握度:面试官不仅仅是想知道你能背出几种策略的名字,更是想看你能否说清楚每种策略的核心思想和实现原理。
  2. 场景选型能力:不同业务场景该用哪种策略?如果你只能说 "默认的就行",那面试官基本就判定你对这块没有深入思考。
  3. 原理理解深度:加权轮询的权重是怎么计算的?一致性哈希的虚拟节点是干嘛的?能聊到这个层次,面试官才会觉得你是真懂,而不是背了个八股文。

核心答案

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 优先选最快的节点

面试高频追问

  1. Dubbo 默认的负载均衡策略是什么?能改吗?

    • 默认是 Random(加权随机)。可以改,支持全局、服务级、方法级三个粒度配置。
  2. 一致性哈希中,如果某个 Provider 挂了,请求会怎样?

    • 请求会顺时针找到下一个存活的 Provider,不会影响整体可用性。只影响挂掉节点对应的那些请求,其他请求的映射关系不变——这也是一致性哈希 "一致性" 的体现。
  3. 权重是怎么设置的?

    • 可以在 Provider 端通过 dubbo:providerweight 属性设置,也可以通过运维工具(Dubbo Admin)动态调整权重,实现灰度发布或流量调度。
  4. 如果你的服务既有读操作又有写操作,负载均衡策略该怎么选?

    • 读操作可以用 randomleastactive;写操作如果涉及状态(比如写到本地缓存),可以考虑 consistenthash,让同一个实体的写请求固定打到一台机器上,避免数据不一致。

常见面试变体

  • "Dubbo 的 Random 负载均衡是怎么实现加权的?"
  • "一致性哈希在 Dubbo 中是怎么用的?虚拟节点的作用是什么?"
  • "Dubbo 的负载均衡策略可以在哪些层面配置?优先级是什么?"

记忆口诀

5 种策略:随机(默认)、轮询、最少活跃、一致性哈希、最短响应。

选型口诀:通用选随机,差异选活跃,灰度选轮询,有状态选哈希,低延迟选最短。

总结

Dubbo 内置 5 种负载均衡策略,默认用加权随机。面试时不光要能说出名字,更要能讲清楚每种策略的原理和适用场景。最容易加分的地方是结合生产经验谈选型——比如灰度发布用轮询、机器差异大用最少活跃数、有状态服务用一致性哈希,这些才是面试官真正想听到的。