深入解析:【020】Dubbo3从0到1系列之服务发现

声明: 这部分内容依然来自于官网, 按需阅读.

官方文档1

官方文档2

二、服务发现

Dubbo 支持基于注册中心的自动实例发现机制,即 Dubbo 提供者注册实例地址到注册中心,Dubbo 消费者通过订阅注册中心变更事件自动获取最新实例变化,从而确保流量始终转发到正确的节点之上。

Dubbo 目前支持 Nacos、Zookeeper、Kubernetes Service 等多种注册中心接入。

2.1 注册中心

以下是 Dubbo 服务发现接入的一些主流注册中心实现,更多扩展实现与工作原理请查看【注册中心参考】

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

2.1.1 基本使用

开发应用时可以指定 Dubbo 注册中心(registry)组件,配置很简单,只需指定注册中心的集群地址即可:

以 Spring Boot 开发为例,在 application.yml 增加 registry 配置项目

dubbo
registry
address: {protocol}://{cluster-address}

其中,protocol 为选择的配置中心类型,cluster-address 为访问注册中心的集群地址,如

address: nacos://localhost:8848

如需集群格式地址可使用 backup 参数

address: nacos://localhost:8848?backup=localshot:8846,localshot:8847

流的语义保证

  • 3.3.0 及之后的版本可不配置注册中心。而在 3.3.0 版本之前的 Dubbo 应用必须指定注册中心配置,即使不启用注册中心也要配置(可通过设置地址为空 address=‘N/A’ )。

每个注册中心组件有自己特有的配置,可以用来控制命名空间、分组、鉴权等,具体可以参考 registry 配置参考手册或通过 parameters 参数进行扩展。

2.1.2 配置中心与元数据中心

配置中心、元数据中心是实现 Dubbo 高阶服务治理能力会依赖的组件,如流量管控规则等,相比于注册中心通常这两个组件的配置是可选的。

需要注意的是,对于部分注册中心类型(如 Zookeeper、Nacos 等),Dubbo 会默认同时将其用作元数据中心和配置中心(建议保持默认开启状态)。

dubbo
registry
address: nacos://localhost:8848

框架解析后的默认行为:

dubbo
registry
address: nacos://localhost:8848
config-center
address: nacos://localhost:8848
metadata-report
address: nacos://localhost:8848

如果您不想使用 nacos 作为配置中心,可以通过以下两个参数来调整或控制默认行为:

dubbo
registry
address: nacos://localhost:8848
use-as-config-center: false
use-as-metadata-report: false
config-center
address: apollo://localhost:8848

2.2 延迟注册

如果你的服务需要预热时间,比如初始化缓存、等待相关资源就位等,可以使用 delay 参数进行延迟注册。如果是在 Spring 应用中,则 delay = n(n > 0) 延迟的时间是 Spring 上下文初始化完成后开始算起。

@DubboService(delay = 5000)
public class DemoServiceImpl implements DemoService {
}

以上配置后,应用将延迟 5 秒暴露此服务(应用启动 5s 后发布该服务到注册中心)。或者可以配置全局默认值,让所有服务都延迟 5s 后注册:

dubbo:
provider:
delay: 5000

【手动注册】:

通过配置 delay = -1,可以禁止框架自动发布服务到注册中心,直到用户通过调用 online 等命令手动完成发布,可以用这个特性配合部署系统实现服务的优雅上线,让用户对上线时机有更好的控制。具体配置如下:

dubbo:
provider:
delay: -1
application:
manual-register: true

2.3 多注册中心

Dubbo 支持在同一应用内配置多个注册中心,一个或一组服务可同时注册到多个注册中心,一个或一组服务可同时订阅多个中心的地址,对于订阅方而言,还可以设置如何调用来自多个注册中心的地址(优先调用某一个注册中心或者其他策略)。

指定全局默认的一个或多个注册中心,所有的服务默认都注册到或订阅配置的注册中心:

dubbo
registries
beijingRegistry
register-mode: instance # 新用户建议使用,老用户如继续使用老服务发现模型则删除此配置
address: zookeeper://localhost:2181
shanghaiRegistry
register-mode: instance # 新用户建议使用,老用户如继续使用老服务发现模型则删除此配置
address: zookeeper://localhost:2182

指定某个服务注册到多个注册中心:

@DubboService(registry = {"beijingRegistry"})
public class DemoServiceImpl implements DemoService {}

指定某个服务订阅来自多个注册中心的地址:

@DubboReference(registry = {"beijingRegistry"})
private DemoService demoService

2.3.1 设置全局默认注册中心

# application.yml (Spring Boot)
dubbo
registries
beijingRegistry
address: zookeeper://localhost:2181
default: true # 设置默认的注册中心
shanghaiRegistry
address: zookeeper://localhost:2182
default: false # 设置非默认的注册中心

default 用来设置全局默认注册中心,默认值为 true 即被视作全局注册中心。未指定注册中心 id 的服务将自动注册或订阅全局默认注册中心

2.3.2 显示关联服务与注册中心

通过在 Dubbo 服务定义组件上增加 registry 配置,将服务与注册中心关联起来。

@DubboServiceregistry = {"beijingRegistry"}
public class DemoServiceImpl implements DemoService {}
@DubboServiceregistry = {"shanghaiRegistry"}
public class HelloServiceImpl implements HelloService {}

增加以上配置后,DemoService 将只注册到 beijingRegistry,而 HelloService 将注册到 shanghaiRegistry。

2.4 多注意中心订阅

服务订阅由于涉及到地址聚合和路由选址,因此逻辑会更加复杂一些。从单个服务订阅的视角,如果存在多注册中心订阅的情况,则可以根据注册中心间的地址是否聚合分为两种场景。

2.4.1 多注册中心地址不聚合

<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" />
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" />

以上所示独立配置的注册中心组件,地址列表在消费端默认是完全隔离的,负载均衡选址要经过两步:

  1. 注册中心集群间选址,选定一个集群
  2. 注册中心集群内选址,在集群内进行地址筛选

在这里插入图片描述

下面我们着重分析下如何控制 注册中心集群间选址,可选的策略有如下几种 随机 每次请求都随机的分配到一个注册中心集群

随机的过程中会有可用性检查,即每个集群要确保至少有一个地址可用才有可能被选到。

2.4.2 preferred优先

<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" preferred="true"/>
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" />

如果有注册中心集群配置了 preferred="true",则所有流量都会被路由到这个集群。

2.4.3 weighted

<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" weight="100"/>
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" weight="10" />

基于权重的随机负载均衡,以上集群间会有大概 10:1 的流量分布。

2.4.4 同 zone 优先

<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" zone="hangzhou" />
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" zone="qingdao" />
RpcContext.getContext().setAttachment("registry_zone", "qingdao");

根据 Invocation 中带的流量参数或者在当前节点通过 context 上下文设置的参数,流量会被精确的引导到对应的集群。

除了通过 RpcContext 参数设置 zone 外,还可以通过扩展 org.apache.dubbo.rpc.ZoneDetector 实现,以更灵活的方式确定当前请求的 zone 归属。RuleConverter

2.5 多注册中心地址聚合

<dubbo:registry address="multiple://127.0.0.1:2181?separator=;&reference-registry=zookeeper://address11?backup=address12,address13;zookeeper://address21?backup=address22,address23" />

这里增加了一个特殊的 multiple 协议开头的注册中心,其中:

  • multiple://127.0.0.1:2181 并没有什么具体含义,只是一个特定格式的占位符,地址可以随意指定
  • reference-registry 指定了要聚合的注册中心集群的列表,示例中有两个集群,分别是 zookeeper://address11?backup=address12,address13和 zookeeper://address21?backup=address22,address23,其中还特别指定了集群分隔符 separator=";"

如下图所示,不同注册中心集群的地址会被聚合到一个地址池后在消费端做负载均衡或路由选址。

在这里插入图片描述

在 3.1.0 版本及之后,还支持每个注册中心集群上设置特定的 attachments 属性,以实现对该注册中心集群下的地址做特定标记,后续配合 Router 组件扩展如 TagRouter 等就可以实现跨机房间的流量治理能力。

<dubbo:registry address="multiple://127.0.0.1:2181?separator=;&reference-registry=zookeeper://address11?attachments=zone=hangzhou,tag=middleware;zookeeper://address21" />

增加 attachments=zone=hangzhou,tag=middleware 后,所有来自该注册中心的 URL 地址将自动携带 zonetag 两个标识,方便消费端更灵活的做流量治理

2.6 场景示例

2.6.1 场景一:跨区域注册服务

比如:中文站有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心。

<dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" />
<dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" default="false" />
<!-- 向多个注册中心注册 -->
  <dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" registry="hangzhouRegistry,qingdaoRegistry" />

2.6.2 场景二:根据业务实现隔离

CRM 有些服务是专门为国际站设计的,有些服务是专门为中文站设计的。

<!-- 多注册中心配置 -->
  <dubbo:registry id="chinaRegistry" address="10.20.141.150:9090" />
  <dubbo:registry id="intlRegistry" address="10.20.154.177:9010" default="false" />
  <!-- 向中文站注册中心注册 -->
    <dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" registry="chinaRegistry" />
    <!-- 向国际站注册中心注册 -->
      <dubbo:service interface="com.alibaba.hello.api.DemoService" version="1.0.0" ref="demoService" registry="intlRegistry" />

2.6.3 根据业务调用服务

CRM 需同时调用中文站和国际站的 PC2 服务,PC2 在中文站和国际站均有部署,接口及版本号都一样,但连的数据库不一样。

<!-- 多注册中心配置 -->
  <dubbo:registry id="chinaRegistry" address="10.20.141.150:9090" />
  <dubbo:registry id="intlRegistry" address="10.20.154.177:9010" default="false" />
  <!-- 引用中文站服务 -->
    <dubbo:reference id="chinaHelloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" registry="chinaRegistry" />
    <!-- 引用国际站站服务 -->
      <dubbo:reference id="intlHelloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" registry="intlRegistry" />

如果只是测试环境临时需要连接两个不同注册中心,使用竖号分隔多个不同注册中心地址:

<!-- 多注册中心配置,竖号分隔表示同时连接多个不同注册中心,同一注册中心的多个集群地址用逗号分隔 -->
  <dubbo:registry address="10.20.141.150:9090|10.20.154.177:9010" />
  <!-- 引用服务 -->
    <dubbo:reference id="helloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" />

enjoy it

posted @ 2025-11-27 08:47  clnchanpin  阅读(61)  评论(0)    收藏  举报