服务发现与负载均衡

Dubbo 提供的集群负载均衡策略

Dubbo 提供了 client-based 服务发现与负载均衡机制,可自动检测后端服务实例变化且在不同实例间均匀的分发流量,支持 Nacos、Zookeeper、Kubernetes Service 等多种注册中心接入。

服务发现

以下是 Dubbo 服务发现接入的一些主流注册中心实现,更多扩展实现请查看 注册中心参考手册

注册中心配置值服务发现模型是否支持鉴权spring-boot-starter
Nacosnacos应用级、接口级dubbo-nacos-spring-boot-starter
Zookeeperzookeeper应用级、接口级- dubbo-zookeeper-spring-boot-starter
- dubbo-zookeeper-curator5-spring-boot-starter
Kubernetes Service参考下文使用文档应用级

Nacos 注册中心

以 Spring Boot 场景下的应用开发为例,增加以下配置使用基于 Nacos 注册中心的服务发现(Zookeeper 的使用方式类似)。

在项目中添加 macos-client 等相关依赖:

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-nacos-spring-boot-starter</artifactId>
    <version>3.3.0-beta.1</version>
</dependency>

application.yml 文件增加 retistry 注册中心配置。

dubbo:
  registry:
    address: "nacos://127.0.0.1:8848"

之后启动 Dubbo 进程,provider 将自动注册服务和地址到 Nacos server,同时 consumer 自动订阅地址变化。

Dubbo 支持配置到注册中心连接的鉴权,也支持指定命名空间、分组等以实现注册数据的隔离,此外,Dubbo 还支持设置如延迟注册、推空保护、只注册、只订阅等注册订阅行为。 以下是一些简单的配置示例,请查看 注册中心参考手册 了解更多配置详情。

dubbo:
  registry:
    address: "nacos://127.0.0.1:8848"
    group: group1 # use separated group in registry server.
    delay: 10000 # delay registering instance to registry server.
    parameters.namespace: xxx # set target namespace to operate in registry server.
    parameters.key: value # extended key value that will be used when building connection with registry.

Kubernetes 注册中心

Dubbo 支持关于使用 Kubernetes Service 服务发现,由于其架构复杂性,我们有专门的文档展开说明,请参考 Dubbo+Kubernetes 最佳实践

半托管

全托管架构

在这里都描述一下,架构图给看看

基于多个注册中心的发现服务

关于工作原理与更多使用场景说明

服务发现问题排查

相比于 client 到 server 的 RPC 直连调用,开启服务发现后,常常会遇到各种个样奇怪的调用失败问题,以下是一些常见的问题与排查方法。

如果你的项目开启了服务发现,但在测试中想调用某个特定的 ip,可通过设置对端 ip 地址的 直连模式 绕过服务发现机制进行调用。

  1. 消费方地址找不到 (No Provider available)
  2. 忘记配置注册中心,
  3. 注册中心连不上
  4. 消费方启动报错

负载均衡

Dubbo 内置了如下负载均衡算法,结合上文提到的自动服务发现机制,消费端会自动使用 Weighted Random LoadBalance 加权随机负载均衡策略 选址调用。

如果要调整负载均衡算法,以下是 Dubbo 框架内置的负载均衡策略:

算法特性备注配置值
Weighted Random LoadBalance加权随机默认算法,默认权重相同random (默认)
RoundRobin LoadBalance加权轮询借鉴于 Nginx 的平滑加权轮询算法,默认权重相同,roundrobin
LeastActive LoadBalance最少活跃优先 + 加权随机背后是能者多劳的思想leastactive
Shortest-Response LoadBalance最短响应优先 + 加权随机更加关注响应速度shortestresponse
ConsistentHash LoadBalance一致性哈希确定的入参,确定的提供者,适用于有状态请求consistenthash
P2C LoadBalancePower of Two Choice随机选择两个节点后,继续选择“连接数”较小的那个节点。p2c
Adaptive LoadBalance自适应负载均衡在 P2C 算法基础上,选择二者中 load 最小的那个节点adaptive

使用场景

  • 高可用性:部署服务的多个实例以确保即使一个或多个实例失败服务保持可用,负载均衡功能可用于在这些实例之间分配传入的请求确保以负载均衡方式使用每个实例的方式,还能最大限度地降低服务停机的风险。

  • 流量管理:限制指向特定服务实例的流量,以防止过载或确保公平的资源分配,负载均衡特性提供了 Round Robin、Weighted Round Robin、Random、Least Active Load Balancing 等多种负载均衡策略,可以用来实现流量控制。

  • 服务划分:将一个服务划分成多个逻辑组件,每个逻辑组件可以部署在不同的实例上,使用负载平衡以确保每个分区平衡的方式在这些实例之间分配请求,同时在实例发生故障的情况下提供故障转移功能。

  • 性能优化:负载平衡可用于优化服务的性能,通过跨多个实例分发请求可以利用可用的计算资源来缩短响应时间并减少延迟。

使用方式

只需要调整 loadbalance 相应取值即可,每种负载均衡策略取值请参见文档最上方表格。

Dubbo 框架支持为单个服务、服务的单个方法指定独立的负载均衡策略

服务端服务级别

<dubbo:service interface="..." loadbalance="roundrobin" />

客户端服务级别

<dubbo:reference interface="..." loadbalance="roundrobin" />

服务端方法级别

<dubbo:service interface="...">
    <dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:service>

客户端方法级别

<dubbo:reference interface="...">
    <dubbo:method name="..." loadbalance="roundrobin"/>
</dubbo:reference>

一致性哈希配置

默认采用第一个参数作为哈希 key,如果需要切换参数,可以指定 hash.arguments 属性

ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<DemoService>();
// ... init
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("hash.arguments", "1");
parameters.put("sayHello.hash.arguments", "0,1");
referenceConfig.setParameters(parameters);
referenceConfig.setLoadBalance("consistenthash");
referenceConfig.get();

最后修改 December 29, 2023: 20231229 doc (#2887) (f94f27f08a)