Dubbo 2 巩固教程之二

大纲

前言

学习资源

Dubbo 深入理解

学习建议

  • 学习内容

    • 接口代理、注册中心、配置加载
  • 学习方法

    • 接口代理:Dubbo 的接口代理是如何实现的?
    • 注册中心:Dubbo 在 Zookeeper 上面干了什么?
    • 配置加载:Dubbo 配置加载流程、不同粒度配置的覆盖关系是怎样?

特别注意

在学习 Dubbo 的底层源码时,建议使用原生 API 的方式来使用 Dubbo,这样更容易探寻 Dubbo 内部细节的入口。

接口代理

接口代理的底层实现

  • Dubbo 接口代理的底层源码
    • Dubbo 基于接口的代理实现
      • ReferenceConfig.get() -> ReferenceConfig.init() -> ReferenceConfig.createProxy() -> StubProxyFactoryWrapper.getProxy() -> JavassistProxyFactory.getProxy() -> DubboInvoker.doInvoke()
    • Nettty 在远程过程调用的应用
      • NettyClient.doOpen() -> NettyClientHandler
      • NettyServer.doOpen() -> NettyHandler

支持的动态代理策略

  • Dubbo 支持的动态代理策略有以下三种

    • Javassist(基于字节码):默认,使用 Javassist 字节码操作库生成代理类。
    • JDK 动态代理(基于反射):使用 JDK 动态代理生成代理类。
    • CGLib(基于 ASM):使用 CGLib 字节码操作库生成代理类。
  • Dubbo 默认使用 Javassist 来实现动态代理,而不是使用 CGlib 的原因如下

原因说明
功能冗余 Dubbo 只需要接口代理,CGlib 面向类代理,其优势无法发挥。
Javassist 足够优秀生成速度快,运行性能高,API 友好,完全可以替代 CGlib。
依赖冲突 Spring 等框架也使用 CGlib,如果 Dubbo 也使用 CGlib 容易产生版本冲突和类加载问题。
维护成本高 ASM 对 JDK 版本敏感,Dubbo 不希望承担额外的版本升级压力,增加维护成本。
社区策略 Dubbo 官方逐步废弃 CGlib,未来版本彻底移除。

提示

Dubbo 默认使用 Javassist 字节码操作来生成代理类,还可以通过 Dubbo 的 SPI 扩展机制配置用户自己的动态代理实现。

注册中心

Dubbo 官方文档

更多关于 Dubbo 注册中心的介绍请看 Dubbo 官方文档 - 注册中心与服务发现

支持的注册中心

Dubbo 支持的注册中心有以下几种(不限于):

Dubbo 3 支持的注册中心类型

在 Dubbo 3 中,默认支持 ZooKeeper 与 Nacos 作为注册中心,而且 Dubbo 扩展生态提供了 Consul、Etcd、Redis、Multicast 等注册中心的扩展实现,还支持 Kubernetes、Mesh 体系的服务发现。

ZK 注册中心使用

ZooKeeper 注册中心的底层源码

  • Dubbo 中 ZooKeeper 注册中心相关的底层源码:
    • 将服务注册到 ZooKeeper
      • ZookeeperRegistry.doRegister()
    • 从 ZooKeeper 订阅服务
      • ZookeeperRegistry.doSubscribe()

ZooKeeper 注册中心的存储结构

  • Dubbo 在 ZooKeeper 注册中心中的数据存储结构和数据格式(如下图所示):

1
2
3
4
5
6
7
8
9
10
11
12
13
/dubbo
└── com.clay.dubbo.service.DemoService
├── providers
│ └── [dubbo%3A%2F%2F127.0.0.1%3A20880%2Fcom.clay.dubbo.service.DemoService%3Fanyhost%3Dtrue%26application%3Ddubbo-provider-application%26bean.name%3Dcom.clay.dubbo.service.DemoService%26dubbo%3D2.0.2%26generic%3Dfalse%26interface%3Dcom.clay.dubbo.service.DemoService%26methods%3DsayHello%26pid%3D36945%26side%3Dprovider%26timestamp%3D1735281570416]

├── consumers
│ └── [consumer%3A%2F%2F172.17.0.1%2Fcom.clay.dubbo.service.DemoService%3Fapplication%3Ddubbo-consumer-application%26category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.0.2%26init%3Dfalse%26interface%3Dcom.clay.dubbo.service.DemoService%26loadbalance%3Drandom%26metadata-type%3Dremote%26methods%3DsayHello%26pid%3D2581%26qos.enable%3Dfalse%26release%3D2.7.23%26retries%3D0%26side%3Dconsumer%26sticky%3Dfalse%26timeout%3D1000%26timestamp%3D1758801158327]

├── configurators
│ └── empty

└── routers
└── empty
  • Dubbo 在 ZooKeeper 注册中心的核心目录说明:
    • 服务级注册 / 配置目录
      • 目录路径:/dubbo/{serviceInterface}/{type}/
        • {serviceInterface} 是具体服务接口的全限定名
        • {type} 包括:
          • providers:服务提供者注册的 URL
          • consumers:服务消费者注册的 URL
          • routers:服务级的路由规则
          • configurators:服务级的动态配置规则
      • 主要作用:
        • 用于存储服务提供者、服务消费者的注册信息
        • 用于存储服务级的路由规则(如条件路由、标签路由等)
        • 用于存储服务级的动态配置规则(如超时时间、重试次数、负载均衡策略等)
      • 适用场景:
        • 服务提供者与服务消费者的注册发现
        • 针对某个服务接口的专属路由规则(如条件路由、标签路由等)
        • 针对某个服务接口的的专属治理策略(如超时时间、重试次数、负载均衡策略等)
        • 服务接口级的灰度发布、金丝雀发布
        • 服务接口级的熔断、降级、流控策略
        • 服务接口级的黑白名单 / 权限控制
        • 服务接口级的 Mock(服务降级) / 故障模拟配置
        • 针对特定 version / group 的差异化治理

查看 ZooKeeper 注册中心的数据

  • 查看 ZooKeeper 的节点信息(Root Node)
1
2
[zk: localhost:2181(CONNECTED) 7] ls /dubbo
[com.clay.dubbo.service.DemoService, config, metadata]
  • 查看 ZooKeeper 的节点信息(Service)
1
2
[zk: localhost:2181(CONNECTED) 9] ls /dubbo/com.clay.dubbo.service.DemoService
[configurators, consumers, providers, routers]
  • 查看 ZooKeeper 的节点信息(Provider - 服务提供者),默认通过 URLEncoder 进行编码
1
2
[zk: localhost:2181(CONNECTED) 10] ls /dubbo/com.clay.dubbo.service.DemoService/providers 
[dubbo%3A%2F%2F127.0.0.1%3A20880%2Fcom.clay.dubbo.service.DemoService%3Fanyhost%3Dtrue%26application%3Ddubbo-provider-application%26bean.name%3Dcom.clay.dubbo.service.DemoService%26dubbo%3D2.0.2%26generic%3Dfalse%26interface%3Dcom.clay.dubbo.service.DemoService%26methods%3DsayHello%26pid%3D36945%26side%3Dprovider%26timestamp%3D1735281570416]
  • 将上述的节点信息(Provider - 服务提供者)通过 URLDecoder 解码后,得到的内容如下:
1
[dubbo://127.0.0.1:20880/com.clay.dubbo.service.DemoService?anyhost=true&application=dubbo-provider-application&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.clay.dubbo.service.DemoService&methods=sayHello&pid=24895&release=2.7.6&side=provider&timestamp=1735287128612]

多注册中心注册

Dubbo 支持同一个服务向多个注册中心同时注册,或者不同的服务分别注册到不同的注册中心上去,甚至可以同时引用注册在不同注册中心上的同名服务。

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

  • 不同的服务注册到不同的注册中心。比如:CRM 系统中有些服务是专门为国际站设计的,有些服务是专门为中文站设计的,具体配置如下图所示:

  • 单独引用不同注册中心的服务。比如:CRM 系统中需要同时调用中文站和国际站的 PC2 服务,而 PC2 服务在中文站和国际站均有部署,接口及版本号都一样,但连接的数据库不一样,具体配置如下图所示:

  • 同时引用不同注册中心的同名服务,可以使用竖号分隔多个不同注册中心地址。比如:CRM 系统中需要同时调用中文站和国际站的 Pay 服务,而 Pay 服务在中文站和国际站均有部署,接口及版本号都一样,连接的数据库也一样,具体配置如下图所示:

一个服务多个注册中心的应用场景

注册中心的扩展

扩展接口
  • 扩展说明
    • 负责服务注册与发现
  • 扩展接口
    • org.apache.dubbo.registry.RegistryFactory
    • org.apache.dubbo.registry.Registry
  • 扩展配置
    1
    2
    3
    4
    5
    6
    <!-- 定义注册中心 -->
    <dubbo:registry id="xxx1" address="xxx://ip:port"/>
    <!-- 设置注册中心(服务提供者),如果没有配置 registry 属性,将在 ApplicationContext 中自动扫描 registry 配置 -->
    <dubbo:service registry="xxx1"/>
    <!-- 设置默认注册中心(服务提供者缺省配置),当 <dubbo:sevice> 没有配置 registry 属性时,默认会使用此配置 -->
    <dubbo:provider registry="xxx1"/>
  • 扩展契约

SPI 扩展机制

Dubbo 支持通过 Registry SPI 机制扩展更多的注册中心实现到 Dubbo 生态,比如 Dubbo 官方通过该机制扩展支持了 Consul、Etcd 等注册中心。

  • Java SPI 机制

    • 概述
      • Java 原生支持 SPI 机制,SPI 全称为 Service Provider Interface,是一种服务发现机制。
      • SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器(ServiceLoader)读取配置文件,加载具体的实现类。
      • 这样就可以在运行时,动态为接口替换实现类。因此,开发者可以很容易的通过 SPI 机制为程序提供拓展功能(比如插件功能)。
      • 比如:运行时通过 ServiceLoader 等工具扫描依赖的 Jar 包,在其中查找对应的文件,并加载指定的实现类
        • ServiceLoader<HelloService> loader = ServiceLoader.load(HelloService.class);
    • 使用步骤
      • (1) 定义接口
      • (2) 实现多个接口实现类
      • (3) 在项目的 META-INF/services 目录中新增全限定接口名文件,指定具体的实现类
        • 文件名是接口的全限定名
        • 文件内容是接口实现类的全限定名
    • 应用场景
      • SPI 机制常用于插件式扩展。
      • 比如:如果你在开发一个框架,可以通过 SPI 让外部开发者编写插件,扩展框架的功能,而不必修改框架的源码。
    • 典型案例
      • JDBC
        • Java 标准库只定义了一套 JDBC 接口,并没有真正的实现。
        • 数据库厂商(如 MySQL、Oracle)会提供自己的实现,并通过 SPI 机制声明在 resources/META-INF/services/ 目录中。
        • 运行时,Java 会根据项目引入的数据库驱动 Jar 包,自动找到对应的 JDBC 实现类。
  • Dubbo SPI 机制

    • 概述
      • Dubbo 并未使用 Java SPI 机制,而是重新实现了一套功能更强的 SPI 机制。
      • Dubbo SPI 机制的相关逻辑被封装在 ExtensionLoader 类中,通过 ExtensionLoader,用户可以加载指定的实现类,具体使用步骤跟 Java SPI 稍有不同。
    • 工作原理
      • (1) 接口声明
        • 在 Dubbo 中,如果某个接口需要支持 SPI 扩展,就会加上 @SPI 注解,比如 Protocol 接口:
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          // 接口定义
          @SPI("dubbo")
          public interface Protocol {

          int getDefaultPort();

          @Adaptive
          <T> Exporter<T> export(Invoker<T> invoker) throws RpcException;

          @Adaptive
          <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException;

          void destroy();
          }

          // 加载实现类
          Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
        • @SPI("dubbo") 表示默认实现是 dubbo
        • @Adaptive 表示该方法会生成代理逻辑,运行时根据参数动态选择实现类。
      • (2) 实现类配置
        • Dubbo 在自己 Jar 包中的 resources/META-INF/dubbo/internal/ 路径下提供了一个配置文件,文件名是接口的全限定名,比如:
          1
          resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol
        • 配置文件的内容是 key=实现类的全限定名,key 对应 @SPI 注解中的扩展名称,比如:
          1
          2
          3
          dubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol
          http=com.alibaba.dubbo.rpc.protocol.http.HttpProtocol
          hessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocol
      • (3) 默认实现加载
        • 如果用户没有配置扩展,Dubbo 会根据 @SPI("dubbo") 的默认值 dubbo,从配置文件中加载对应的实现类 DubboProtocol
        • 这也是 Dubbo 默认使用 Dubbo 协议作为 RPC 通信协议的原因。
      • (4) 动态切换实现类
        • Protocol 接口中,有两个方法加了 @Adaptive 注解。
        • Dubbo 会在运行时生成代理类,在代理方法内部根据传入的 URL 参数的 protocol 值决定使用哪个实现类。
        • 如果 URL 参数中没指定协议,就用默认的 dubbo;如果指定了其他值(如 http),则加载对应的实现类。

配置加载

Dubbo 官方文档

更多关于 Dubbo 配置加载的介绍请看 Dubbo 官方文档 - 配置加载流程附文档截图

Dubbo 的配置来源

  • Dubbo 的四种配置来源和优先级高低如下所示,优先级高的会覆盖优先级低的
优先级配置来源说明
1JVM System Properties,通过启动参数 -D 指定最高优先级,通常用于紧急覆盖配置,无需改代码或配置文件,应用重启即可生效。
2Externalized Configuration,外部化配置如 Apollo、Nacos、Spring Cloud Config 等配置中心动态下发的配置。Dubbo 运行时会监听这些配置的变化,支持热更新。
3 编程接口配置,比如 ServiceConfig、ReferenceConfig在代码中直接通过 ServiceConfigReferenceConfig 等 API 设置的参数。优先级低于外部化配置,便于后期通过配置中心进行覆盖。
4 本地配置文件,比如 dubbo.properties最低优先级,通常用于本地开发,或作为兜底默认值。

Dubbo 的核心配置类

Dubbo 的配置类分为 4 大类:应用配置、服务消费方配置、服务提供方配置、公共方法配置。

  • 应用配置
    • ApplicationConfig:配置当前应用的信息,不管该应用是服务提供方还是服务消费方
    • RegistryConfig:配置连接注册中心相关的信息
    • MonitorConfig:配置连接监控中心相关的信息(可选)
    • ModuleConfig:用于配置当前模块的信息(可选)
  • 服务消费方配置
    • RefrenceConfig:创建一个远程服务代理,一个引用可以指向多个注册中心
    • ConsumerConfig:当 ReferenceConfig 中某属性没有配置时,会采用此配置的缺省值(可选),即 ConsumerConfig 相当于服务消费方的全局配置
  • 服务提供方配置
    • ProtocolConfig:配置提供服务的协议信息,协议由提供方指定,消费方被动接受
    • ServiceConfig:暴露单个服务,定义服务的元信息,单个服务可以用多个协议暴露、注册到多个注册中心
    • ProviderConfig:当 ProtocolConfigServiceConfig 中某属性没有配置时,会采用此配置的缺省值(可选),即 ProviderConfig 相当于服务提供方的全局配置
  • 公共方法配置
    • MethodConfig:指定方法级别的配置信息,如超时时间、重试次数、负载均衡策略等,可配置在 ReferenceConfigServiceConfig
    • ArgumentConfig:指定方法参数的配置信息,如参数验证、回调方法等。

不同配置类之间的关系

  • 在 Dubbo 中,配置类之间的引用和继承关系如下图所示(不同版本有所区别)。在引用和继承关系图中,左边是服务提供方的相关配置,右边是服务消费方的相关配置,中间是双方的共享配置,下边是方法和方法参数的相关配置。

  • ReferenceConfig 引用了 ConsumerConfig,而 ServiceConfig 引用了 ProviderConfig
  • 如果没有进行 ReferenceConfig 的配置,默认使用 ConsumerConfig 的配置。
  • 如果没有进行 ServiceConfig 的配置,默认使用 ProviderConfig 的配置。

不同粒度配置的覆盖关系

以超时时间(timeout)的配置为例,下图显示了 Dubbo 配置的查找顺序(从上到下,配置的优先级逐渐降低),其它配置如 retriesloadbalance 等类似。蓝色部分表示服务消费方的配置,绿色部分表示服务提供方的配置。

  • 配置的优先级

    • 优先级高低:方法级别的配置 > 接口级别的配置 > 全局的配置,优先级高的会覆盖优先级低的
      • 精确优先方法级别的配置优先,接口级别的配置次之,全局的配置再次之。
      • 消费方配置优先如果级别一样,则服务消费方的配置优先,服务提供方的配置次之。
    • 其中,服务提供方的配置信息,是通过 URL 经由注册中心(比如 ZooKeeper)传递给服务消费方。
  • 配置的覆盖规则

    • 值得注意的是,下面的 > 符号可以理解为 “覆盖”。
    • 方法级别的配置 > 接口级别的配置,即小 Scope(范围)配置优先。
    • 服务消费方的配置 > 服务提供方的配置 > 全局配置。
    • 最后是 Dubbo Hard Code(硬编码)的配置(详见官方配置文档)。

在 Dubbo 框架中,推荐在服务提供方(Provider)尽量多配置服务消费方(Consumer)相关的属性,主要原因如下:

  • (1) 服务提供方更了解服务性能特征:作为服务的实现者,Provider 比 Consumer 更清楚服务的性能参数,例如方法调用的合理超时时间、重试次数等关键配置。
  • (2) Provider 配置可作为 Consumer 的缺省值:当 Provider 配置相关属性后,如果 Consumer 未显式配置对应项,则会自动使用 Provider 的配置值。这样既避免了 Consumer 不配置时直接使用其全局默认值(可能对当前服务不合理),也提升了配置的可控性和合理性。
  • (3) 此外,从实践角度建议,应由服务提供方设定超时时间、重试次数等关键配置,因为服务执行所需的时长通常只有服务提供方最清楚。这样也能减轻 Consumer 的配置负担,特别是当一个 Consumer 调用多个服务时,无需逐一关注每个服务的超时设置。
  • (4) 从配置约定上看,理论上在 ReferenceConfig 中,除了 interface 为必需配置项之外,其余所有配置项均可缺省。此时框架会自动逐级查找缺省配置,优先使用 ConsumerConfigServiceConfigProviderConfig 中提供的默认值。

提示

  • Dubbo 的引用默认是延迟初始化的,只有引用被注入到其它 Bean,或被 getBean() 获取才会初始化。如果需要饥饿加载,即没有被引用也立即生成动态代理对象,可以配置:<dubbo:reference ... init="true"/>
  • 在服务消费方配置一个接口级别的配置超时时间是 5000,而在服务提供方配置一个方法级别精确的超时时间为 1000,配置为 <dubbo:method name="getUserList" timeout"1000">,这个情况下生效的是服务提供方配置的超时时间 1000;因为方法级别的配置优先级更高,只有配置级别一样时,服务消费方的配置才优先。

不同配置文件的覆盖关系

下图显示了 Dubbo 配置文件的优先级高低(从上到下,优先级逐渐降低),优先级高的会覆盖优先级低的

  • 配置文件的优先级
    • JVM 启动参数(-D
      • 优先级最高
      • 可在服务部署和启动时通过 -D 参数动态覆盖配置,例如修改协议端口:
        1
        java -Ddubbo.protocol.port=20890 -jar app.jar
      • 适用于临时 / 紧急覆盖配置,无需改代码或配置文件,应用重启即可生效。
    • XML 配置文件
      • 优先级次于 JVM 启动参数(-D
      • 如果在 XML 文件中配置了某项内容,则 Properties 配置文件(如 dubbo.properties)中对应的配置项将失效。
    • Properties 配置文件
      • 优先级最低
      • 仅当 XML 中未配置某项内容时才会生效,相当于默认值。
      • 通常用于本地开发存放公共或共享配置,例如应用名称等基础配置。

配置项分类和配置项格式

  • 配置项的分类

    • (1) 服务发现:表示该配置项用于服务的注册与发现,目的是让服务消费方找到服务提供方。
    • (2) 服务治理:表示该配置项用于治理服务间的关系,或为开发测试提供便利条件。
    • (3) 性能调优:表示该配置项用于调优性能,不同的配置项对性能会产生影响。
  • 配置项的格式

Dubbo 配置参考手册

Dubbo 完整的可配置项列表可以看 Dubbo 官方文档(最新版本)- 配置项参考手册附文档截图

Dubbo 支持的 XML 配置标签

Dubbo 支持的 XML 配置标签如下表所示:

Dubbo 的外部化配置(配置中心)

Dubbo 外部化配置的介绍

  • Dubbo 外部化配置和其他本地配置在内容和格式上并没有任何区别,可以简单理解为 dubbo.properties 的外部化存储,配置中心更适合将一些公共配置(如注册中心、元数据中心等配置)抽取出来,以便做集中管理。

  • Dubbo 外部化配置的主要目的是实现配置的集中式管理,支持的成熟配置系统有:ZooKeeper、Apollo、Nacos、Etcd、Consul,而 Dubbo 做的主要是支持这些配置系统正常工作,让集成更加方便。

  • 举个例子:当 Dubbo 使用 Apollo、Nacos 等配置中心后,可以将以下全局配置(比如注册中心地址、元数据中心地址、协议、QOS 等)统一存储在配置中心,这样应用在本地就不再需要配置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 将注册中心地址、元数据中心地址、协议、QOS 等配置存储在配置中心(如 Nacos),这样可以做到统一管理、减少开发侧感知

    dubbo.application.qos.qosEnable=true
    dubbo.application.qos.port=33333

    dubbo.registry.address=zookeeper://127.0.0.1:2181
    dubbo.registry.simplified=true

    dubbo.metadata-report.address=zookeeper://127.0.0.1:2181

    dubbo.protocol.name=dubbo
    dubbo.protocol.port=20880
  • 当 Dubbo 使用 ZooKeeper 作为配置中心时,ZooKeeper 中的数据存储结构如下图所示:

  • 当 Dubbo 使用 ZooKeeper 作为配置中心时,Dubbo 在 ZooKeeper 中的目录结构分为两类:

    • 全局级配置目录
      • 目录路径:/dubbo/config/dubbo/
      • 主要作用:
        • 存放全局生效的治理规则
        • 例如:全局动态配置(Dynamic Config)、全局路由规则等
      • 影响范围:
        • 所有应用、所有服务均可使用
      • 适用场景:
        • 全局级的动态配置(默认超时时间、默认重试次数、默认负载均衡等)
        • 全局级的路由规则(统一的流控、统一标签路由等)
        • 全局级的黑白名单、限流、熔断、降级等治理策略
        • 全局级的统一开关(如全局灰度、全局 Mock 开关)
        • 全局运维规则下发(例如,统一切换流量策略)
    • 应用级配置目录
      • 目录路径:/dubbo/config/{application}/
        • {application} 是应用名称
      • 主要作用:
        • 用于存放某个应用的动态配置或路由规则
      • 影响范围:
        • 同一个应用内的所有服务接口(不跨应用)
      • 适用场景:
        • 应用级的路由规则
        • 应用级的动态配置(如自定义超时时间、重试次数)
        • 条件路由、标签路由等应用级治理策略
        • 应用级的黑白名单、限流、降级策略
        • 为应用内所有服务统一设置默认负载均衡、超时等治理规则
        • 针对特定应用的测试环境 / 灰度环境治理策略统一下发

Dubbo 外部化配置的优先级

  • 优先级:外部化配置默认比本地配置拥有更高的优先级,因此这里配置的内容会覆盖本地配置值。
  • 作用域:外部化配置有全局和应用两个级别,全局配置是所有应用共享的,应用级配置是由每个应用自己维护且只对自身可见的。当前已支持的扩展实现有 Zookeeper、Apollo、Nacos 等。

Dubbo 外部化配置的使用步骤

  • (1) 增加 config-center 配置(用于指定配置中心地址),比如:<dubbo:config-center address="nacos://127.0.0.1:8848"/>

  • (2) 在相应的配置中心(Zookeeper、Nacos 等)增加全局配置项(如下图所示,以 Nacos 为例)

    • 开启外部化配置后,registrymetadata-reportprotocolqos 等全局范围的配置理论上都不再需要在应用中配置,应用开发侧专注业务服务配置,一些全局共享的全局配置转而由运维人员统一配置在远端配置中心。
    • 这样能做到的效果就是,应用只需要关心:
      • 服务暴露、订阅服务;
      • 配置中心地址当部署到不同的环境时,其他配置就能自动的被从对应的配置中心读取到。
    • 举例来说,每个应用中 Dubbo 相关的全局配置(比如 application.yml)只要有以下内容可能就足够了,其余的配置都托管给相应环境下的配置中心:
      1
      2
      3
      4
      5
      dubbo
      application
      name: demo
      config-center
      address: nacos://127.0.0.1:8848