以下是一个 Dubbo 属性配置的例子 dubbo-spring-boot-samples

  1. ## application.properties
  2. # Spring boot application
  3. spring.application.name=dubbo-externalized-configuration-provider-sample
  4. # Base packages to scan Dubbo Component: @com.alibaba.dubbo.config.annotation.Service
  5. dubbo.scan.base-packages=com.alibaba.boot.dubbo.demo.provider.service
  6. # Dubbo Application
  7. ## The default value of dubbo.application.name is ${spring.application.name}
  8. ## dubbo.application.name=${spring.application.name}
  9. # Dubbo Protocol
  10. dubbo.protocol.name=dubbo
  11. dubbo.protocol.port=12345
  12. ## Dubbo Registry
  13. dubbo.registry.address=N/A
  14. ## service default version
  15. dubbo.provider.version=1.0.0

接下来,我们就围绕这个示例,分别从配置格式、配置来源、加载流程三个方面对 Dubbo 配置的工作原理进行分析。

1 配置格式

目前Dubbo支持的所有配置都是.properties格式的,包括-DExternalized Configuration等,.properties中的所有配置项遵循一种path-based的配置格式。

在Spring应用中也可以将属性配置放到application.yml中,其树层次结构的方式可读性更好一些。

  1. # 应用级配置(无id)
  2. dubbo.{config-type}.{config-item}={config-item-value}
  3. # 实例级配置(指定id或name)
  4. dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
  5. dubbo.{config-type}s.{config-name}.{config-item}={config-item-value}
  6. # 服务接口配置
  7. dubbo.service.{interface-name}.{config-item}={config-item-value}
  8. dubbo.reference.{interface-name}.{config-item}={config-item-value}
  9. # 方法配置
  10. dubbo.service.{interface-name}.{method-name}.{config-item}={config-item-value}
  11. dubbo.reference.{interface-name}.{method-name}.{config-item}={config-item-value}
  12. # 方法argument配置
  13. dubbo.reference.{interface-name}.{method-name}.{argument-index}.{config-item}={config-item-value}

1.1 应用级配置(无id)

应用级配置的格式为:配置类型单数前缀,无id/name。

  1. # 应用级配置(无id)
  2. dubbo.{config-type}.{config-item}={config-item-value}

类似 applicationmonitormetrics 等都属于应用级别组件,因此仅允许配置单个实例;而 protocolregistry 等允许配置多个的组件,在仅需要进行单例配置时,可采用此节描述的格式。常见示例如下:

  1. dubbo.application.name=demo-provider
  2. dubbo.application.qos-enable=false
  3. dubbo.registry.address=zookeeper://127.0.0.1:2181
  4. dubbo.protocol.name=dubbo
  5. dubbo.protocol.port=-1

1.2 实例级配置(指定id或name)

针对某个实例的属性配置需要指定id或者name,其前缀格式为:配置类型复数前缀 + id/name。适用于 protocolregistry 等支持多例配置的组件。

  1. # 实例级配置(指定id或name)
  2. dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
  3. dubbo.{config-type}s.{config-name}.{config-item}={config-item-value}
  • 如果不存在该id或者name的实例,则框架会基于这里列出来的属性创建配置组件实例。
  • 如果已存在相同id或name的实例,则框架会将这里的列出的属性作为已有实例配置的补充,详细请参考属性覆盖
  • 具体的配置复数形式请参考单复数配置对照表

配置示例:

  1. dubbo.registries.unit1.address=zookeeper://127.0.0.1:2181
  2. dubbo.registries.unit2.address=zookeeper://127.0.0.1:2182
  3. dubbo.protocols.dubbo.name=dubbo
  4. dubbo.protocols.dubbo.port=20880
  5. dubbo.protocols.hessian.name=hessian
  6. dubbo.protocols.hessian.port=8089

1.3 服务接口配置

  1. dubbo.service.org.apache.dubbo.samples.api.DemoService.timeout=5000
  2. dubbo.reference.org.apache.dubbo.samples.api.DemoService.timeout=6000

方法配置

方法配置格式:

  1. # 方法配置
  2. dubbo.service.{interface-name}.{method-name}.{config-item}={config-item-value}
  3. dubbo.reference.{interface-name}.{method-name}.{config-item}={config-item-value}
  4. # 方法argument配置
  5. dubbo.reference.{interface-name}.{method-name}.{argument-index}.{config-item}={config-item-value}

方法配置示例:

  1. dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.timeout=7000
  2. dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.oninvoke=notifyService.onInvoke
  3. dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.onreturn=notifyService.onReturn
  4. dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.onthrow=notifyService.onThrow
  5. dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.0.callback=true

等价于XML配置:

  1. <dubbo:reference interface="org.apache.dubbo.samples.api.DemoService" >
  2. <dubbo:method name="sayHello" timeout="7000" oninvoke="notifyService.onInvoke"
  3. onreturn="notifyService.onReturn" onthrow="notifyService.onThrow">
  4. <dubbo:argument index="0" callback="true" />
  5. </dubbo:method>
  6. </dubbo:reference>

1.4 参数配置

parameters参数为map对象,支持xxx.parameters=[{key:value},{key:value}]方式进行配置。

  1. dubbo.application.parameters=[{item1:value1},{item2:value2}]
  2. dubbo.reference.org.apache.dubbo.samples.api.DemoService.parameters=[{item3:value3}]

1.5 传输层配置

triple协议采用Http2做底层通信协议,允许使用者自定义Http2的6个settings参数

配置格式如下:

  1. # 通知对端header压缩索引表的上限个数
  2. dubbo.rpc.tri.header-table-size=4096
  3. # 启用服务端推送功能
  4. dubbo.rpc.tri.enable-push=false
  5. # 通知对端允许的最大并发流数
  6. dubbo.rpc.tri.max-concurrent-streams=2147483647
  7. # 声明发送端的窗口大小
  8. dubbo.rpc.tri.initial-window-size=1048576
  9. # 设置帧的最大字节数
  10. dubbo.rpc.tri.max-frame-size=32768
  11. # 通知对端header未压缩的最大字节数
  12. dubbo.rpc.tri.max-header-list-size=8192

等价于yml配置:

  1. dubbo:
  2. rpc:
  3. tri:
  4. header-table-size: 4096
  5. enable-push: false
  6. max-concurrent-streams: 2147483647
  7. initial-window-size: 1048576
  8. max-frame-size: 32768
  9. max-header-list-size: 8192

1.6 属性与XML配置映射规则

可以将 xml 的 tag 名和属性名组合起来,用 ‘.’ 分隔。每行一个属性。

  • dubbo.application.name=foo 相当于 <dubbo:application name="foo" />
  • dubbo.registry.address=10.20.153.10:9090 相当于 <dubbo:registry address="10.20.153.10:9090" />

如果在 xml 配置中有超过一个的 tag,那么你可以使用 ‘id’ 进行区分。如果你不指定id,它将作用于所有 tag。

  • dubbo.protocols.rmi.port=1099 相当于 <dubbo:protocol id="rmi" name="rmi" port="1099" />
  • dubbo.registries.china.address=10.20.153.10:9090 相当于 <dubbo:registry id="china" address="10.20.153.10:9090" />

1.7 配置项单复数对照表

复数配置的命名与普通单词变复数的规则相同:

  1. 字母y结尾时,去掉y,改为ies
  2. 字母s结尾时,加es
  3. 其它加s
Config Type 单数配置 复数配置
application dubbo.application.xxx=xxx dubbo.applications.{id}.xxx=xxx
dubbo.applications.{name}.xxx=xxx
protocol dubbo.protocol.xxx=xxx dubbo.protocols.{id}.xxx=xxx
dubbo.protocols.{name}.xxx=xxx
module dubbo.module.xxx=xxx dubbo.modules.{id}.xxx=xxx
dubbo.modules.{name}.xxx=xxx
registry dubbo.registry.xxx=xxx dubbo.registries.{id}.xxx=xxx
monitor dubbo.monitor.xxx=xxx dubbo.monitors.{id}.xxx=xxx
config-center dubbo.config-center.xxx=xxx dubbo.config-centers.{id}.xxx=xxx
metadata-report dubbo.metadata-report.xxx=xxx dubbo.metadata-reports.{id}.xxx=xxx
ssl dubbo.ssl.xxx=xxx dubbo.ssls.{id}.xxx=xxx
metrics dubbo.metrics.xxx=xxx dubbo.metricses.{id}.xxx=xxx
provider dubbo.provider.xxx=xxx dubbo.providers.{id}.xxx=xxx
consumer dubbo.consumer.xxx=xxx dubbo.consumers.{id}.xxx=xxx
service dubbo.service.{interfaceName}.xxx=xxx
reference dubbo.reference.{interfaceName}.xxx=xxx
method dubbo.service.{interfaceName}.{methodName}.xxx=xxx
dubbo.reference.{interfaceName}.{methodName}.xxx=xxx
argument dubbo.service.{interfaceName}.{methodName}.{arg-index}.xxx=xxx

2 配置来源

Dubbo 默认支持 6 种配置来源:

  • JVM System Properties,JVM -D 参数
  • System environment,JVM进程的环境变量
  • Externalized Configuration,外部化配置,从配置中心读取
  • Application Configuration,应用的属性配置,从Spring应用的Environment中提取"dubbo"打头的属性集
  • API / XML /注解等编程接口采集的配置可以被理解成配置来源的一种,是直接面向用户编程的配置采集方式
  • 从classpath读取配置文件 dubbo.properties

关于dubbo.properties属性:

  1. 如果在 classpath 下有超过一个 dubbo.properties 文件,比如,两个 jar 包都各自包含了 dubbo.properties,dubbo 将随机选择一个加载,并且打印错误日志。
  2. Dubbo 可以自动加载 classpath 根目录下的 dubbo.properties,但是你同样可以使用 JVM 参数来指定路径:-Ddubbo.properties.file=xxx.properties

2.1 覆盖关系

如果通过多种配置来源指定了相同的配置项,则会出现配置项的互相覆盖,具体覆盖关系和优先级请参考下一小节。

3 配置加载流程

3.1 处理流程

Dubbo 配置加载大概分为两个阶段:

  • 第一阶段为DubboBootstrap初始化之前,在Spring context启动时解析处理XML配置/注解配置/Java-config 或者是执行API配置代码,创建config bean并且加入到ConfigManager中。
  • 第二阶段为DubboBootstrap初始化过程,从配置中心读取外部配置,依次处理实例级属性配置和应用级属性配置,最后刷新所有配置实例的属性,也就是属性覆盖

3.2 属性覆盖

发生属性覆盖可能有两种情况,并且二者可能是会同时发生的:

  1. 不同配置源配置了相同的配置项
  2. 相同配置源,但在不同层次指定了相同的配置项

3.2.1 不同配置源

3.2.1 相同配置源

属性覆盖是指用配置的属性值覆盖config bean实例的属性,类似Spring PropertyOverrideConfigurer 的作用。

Property resource configurer that overrides bean property values in an application context definition. It pushes values from a properties file into bean definitions.

Configuration lines are expected to be of the following form:

beanName.property=value

但与PropertyOverrideConfigurer的不同之处是,Dubbo的属性覆盖有多个匹配格式,优先级从高到低依次是:

  1. #1. 指定id的实例级配置
  2. dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
  3. #2. 指定name的实例级配置
  4. dubbo.{config-type}s.{config-name}.{config-item}={config-item-value}
  5. #3. 应用级配置(单数配置)
  6. dubbo.{config-type}.{config-item}={config-item-value}

属性覆盖处理流程:

按照优先级从高到低依次查找,如果找到此前缀开头的属性,则选定使用这个前缀提取属性,忽略后面的配置。

3.3 外部化配置

外部化配置目的之一是实现配置的集中式管理,这部分业界已经有很多成熟的专业配置系统如 Apollo, Nacos 等,Dubbo 所做的主要是保证能配合这些系统正常工作。

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

  1. # 将注册中心地址、元数据中心地址等配置集中管理,可以做到统一环境、减少开发侧感知。
  2. dubbo.registry.address=zookeeper://127.0.0.1:2181
  3. dubbo.registry.simplified=true
  4. dubbo.metadata-report.address=zookeeper://127.0.0.1:2181
  5. dubbo.protocol.name=dubbo
  6. dubbo.protocol.port=20880
  7. dubbo.application.qos.port=33333
  • 优先级

    外部化配置默认较本地配置有更高的优先级,因此这里配置的内容会覆盖本地配置值,关于各配置形式间的覆盖关系 有单独一章说明。

  • 作用域

    外部化配置有全局和应用两个级别,全局配置是所有应用共享的,应用级配置是由每个应用自己维护且只对自身可见的。当前已支持的扩展实现有 Zookeeper、Apollo、Nacos。

3.3.1 外部化配置使用方式

  1. 增加 config-center 配置
  1. <dubbo:config-center address="zookeeper://127.0.0.1:2181"/>
  1. 在相应的配置中心(zookeeper、Nacos 等)增加全局配置项,如下以 Nacos 为例:

开启外部化配置后,registry、metadata-report、protocol、qos 等全局范围的配置理论上都不再需要在应用中配置,应用开发侧专注业务服务配置,一些全局共享的全局配置转而由运维人员统一配置在远端配置中心。

这样能做到的效果就是,应用只需要关心:

  • 服务暴露、订阅配置
  • 配置中心地址

    当部署到不同的环境时,其他配置就能自动的被从对应的配置中心读取到。

举例来说,每个应用中 Dubbo 相关的配置只有以下内容可能就足够了,其余的都托管给相应环境下的配置中心:

  1. dubbo
  2. application
  3. name: demo
  4. config-center
  5. address: nacos://127.0.0.1:8848

3.3.2 自行加载外部化配置

所谓 Dubbo 对配置中心的支持,本质上就是把 .properties 从远程拉取到本地,然后和本地的配置做一次融合。理论上只要 Dubbo 框架能拿到需要的配置就可以正常的启动,它并不关心这些配置是自己加载到的还是应用直接塞给它的,所以Dubbo还提供了以下API,让用户将自己组织好的配置塞给 Dubbo 框架(配置加载的过程是用户要完成的),这样 Dubbo 框架就不再直接和 Apollo 或 Zookeeper 做读取配置交互。

  1. // 应用自行加载配置
  2. Map<String, String> dubboConfigurations = new HashMap<>();
  3. dubboConfigurations.put("dubbo.registry.address", "zookeeper://127.0.0.1:2181");
  4. dubboConfigurations.put("dubbo.registry.simplified", "true");
  5. //将组织好的配置塞给Dubbo框架
  6. ConfigCenterConfig configCenter = new ConfigCenterConfig();
  7. configCenter.setExternalConfig(dubboConfigurations);

欢迎在 https://github.com/apache/dubbo 给 Dubbo Star。

搜索关注官方微信公众号:Apache Dubbo,了解更多业界最新动态,掌握大厂面试必备 Dubbo 技能

一文了解 Dubbo 3 配置工作原理的更多相关文章

  1. 「MoreThanJava」一文了解二进制和CPU工作原理

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  2. 基于CAS实现单点登录(SSO):工作原理

    工作中使用到了SSO,网上看到了这个博客的一系列文章感觉不错,转载收藏 源地址http://blog.csdn.net/tch918/article/details/19930037 系列文章的第一篇 ...

  3. 说一下Dubbo 的工作原理?注册中心挂了可以继续通信吗?

    面试题 说一下的 dubbo 的工作原理?注册中心挂了可以继续通信吗?说说一次 rpc 请求的流程? 面试官心理分析 MQ.ES.Redis.Dubbo,上来先问你一些思考性的问题.原理,比如 kaf ...

  4. dubbo的工作原理

    dubbo工作原理 第一层:service层,接口层,给服务提供者和消费者来实现的 第二层:config层,配置层,主要是对dubbo进行各种配置的 第三层:proxy层,服务代理层,透明生成客户端的 ...

  5. LVS负载均衡机制之LVS-DR模式工作原理以及简单配置

    本博文主要简单介绍一下LVS负载均衡集群的一个基本负载均衡机制:LVS-DR:如有汇总不当之处,请各位在评论中多多指出. LVS-DR原理: LVS的英文全称是Linux Virtual Server ...

  6. NFS笔记(一)NFS服务器工作原理及详细配置

    一.NFS工作原理 1.什么是NFS服务器 NFS就是Network File System的缩写,它最大的功能就是可以通过网络,让不同的机器.不同的操作系统可以共享彼此的文件. NFS服务器可以让P ...

  7. 1.说一下的 dubbo 的工作原理?注册中心挂了可以继续通信吗?说说一次 rpc 请求的流程?

    作者:中华石杉 面试题 说一下的 dubbo 的工作原理?注册中心挂了可以继续通信吗?说说一次 rpc 请求的流程? 面试官心理分析 MQ.ES.Redis.Dubbo,上来先问你一些思考性的问题.原 ...

  8. [转帖]keepalived工作原理和配置、使用

    keepalived工作原理和配置.使用 https://www.iteye.com/blog/aoyouzi-2288124 keepalived是什么 keepalived是集群管理中保证集群高可 ...

  9. 分布式的几件小事(二)dubbo的工作原理

    1.dubbo的工作原理 ①整体设计 图例说明: 图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口. 图中从下至上分为十层,各层均为单 ...

  10. 面试系列22 dubbo的工作原理

    (1)dubbo工作原理 第一层:service层,接口层,给服务提供者和消费者来实现的 第二层:config层,配置层,主要是对dubbo进行各种配置的 第三层:proxy层,服务代理层,透明生成客 ...

随机推荐

  1. esp32把玩记-④ 星星点灯 (点亮led)

    注意 全程使用Micropython,不会安装看我第一篇文章感谢 正式开始 用Thonny烧录(运行)以下代码 import time from machine import Pin led=Pin( ...

  2. 使用LEFT JOIN 统计左右存在的数据

    最近做了一个数据模块的统计,统计企业收款.发票相关的数据,开始统计是比较简单,后面再拆分账套统计就有点小复杂,本文做一个简单的记录. 需求 企业表 企业表t_company有如下字段:标识id.企业名 ...

  3. 知识图谱顶会论文(ACL-2022) CAKE:用于多视图KGC的可扩展常识感知框架

    CAKE:用于多视图KGC的可扩展常识感知框架.pdf 论文地址:CAKE:Scalable Commonsense-Aware Framework For Multi-View Knowledge ...

  4. 使用dotnet-monitor sidecar模式 dump docker运行的dotnet程序.

    前情概要 随着容器和云技术的发展, 大量的应用运行在云上的容器中, 它们的好处是毋庸置疑的, 例如极大的提高了我们的研发部署速度, 快速的扩缩容等等, 但是也存在一些小小的问题, 例如难以调试. 基于 ...

  5. 实现将机器A上的程序包复制到机器B并更新的脚本

    一.前言 之前有写过如何在单台服务器上执行脚本自动更新程序包,但平时测试过程中相信大部分公司都是需要测试人员在服务器A上进行功能测试,测试通过后再将程序包更新到服务器B上进行安全测试或者性能测试:今天 ...

  6. 有趣的 Go HttpClient 超时机制

    hello,大家好呀,我是既写 Java 又写 Go 的小楼,在写 Go 的过程中经常对比这两种语言的特性,踩了不少坑,也发现了不少有意思的地方,今天就来聊聊 Go 自带的 HttpClient 的超 ...

  7. 【深入浅出 Yarn 架构与实现】3-2 Yarn Client 编写

    上篇文章介绍了编写 Yarn Application 的整体框架流程,本篇文章将详细介绍其中 Client 部分的编写方式. 一.Yarn Client 编写方法 本篇代码已上传 Github: Gi ...

  8. 13.django-admin组件

    Django内置了一个强大的组件叫Admin,提供给网站管理员快速开发运营后台的管理站点,下面通过案例进行操作 1.创建模型类 模型类如下: from django.db import models ...

  9. 华为云平台部署教程之CNA\VRM的安装

    本教程仅含华为云平台搭建部署中CNA和VRM的安装,请按需求选择查看本文. 一.前期准备 1.硬件 服务器*4 交换机*3 网线 个人PC机 2.软件 PC机系统(win7/win10) KVM软件 ...

  10. Java开发学习(四十五)----MyBatisPlus查询语句之映射匹配兼容性

    1.映射匹配兼容性 我们已经能从表中查询出数据,并将数据封装到模型类中,这整个过程涉及到一张表和一个模型类: 之所以数据能够成功的从表中获取并封装到模型对象中,原因是表的字段列名和模型类的属性名一样. ...