以下是一个 Dubbo 属性配置的例子 dubbo-spring-boot-samples
## application.properties
# Spring boot application
spring.application.name=dubbo-externalized-configuration-provider-sample
# Base packages to scan Dubbo Component: @com.alibaba.dubbo.config.annotation.Service
dubbo.scan.base-packages=com.alibaba.boot.dubbo.demo.provider.service
# Dubbo Application
## The default value of dubbo.application.name is ${spring.application.name}
## dubbo.application.name=${spring.application.name}
# Dubbo Protocol
dubbo.protocol.name=dubbo
dubbo.protocol.port=12345
## Dubbo Registry
dubbo.registry.address=N/A
## service default version
dubbo.provider.version=1.0.0
接下来,我们就围绕这个示例,分别从配置格式、配置来源、加载流程三个方面对 Dubbo 配置的工作原理进行分析。
目前Dubbo支持的所有配置都是.properties
格式的,包括-D
、Externalized Configuration
等,.properties
中的所有配置项遵循一种path-based
的配置格式。
在Spring应用中也可以将属性配置放到application.yml
中,其树层次结构的方式可读性更好一些。
# 应用级配置(无id)
dubbo.{config-type}.{config-item}={config-item-value}
# 实例级配置(指定id或name)
dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
dubbo.{config-type}s.{config-name}.{config-item}={config-item-value}
# 服务接口配置
dubbo.service.{interface-name}.{config-item}={config-item-value}
dubbo.reference.{interface-name}.{config-item}={config-item-value}
# 方法配置
dubbo.service.{interface-name}.{method-name}.{config-item}={config-item-value}
dubbo.reference.{interface-name}.{method-name}.{config-item}={config-item-value}
# 方法argument配置
dubbo.reference.{interface-name}.{method-name}.{argument-index}.{config-item}={config-item-value}
应用级配置的格式为:配置类型单数前缀,无id/name。
# 应用级配置(无id)
dubbo.{config-type}.{config-item}={config-item-value}
类似 application
、monitor
、metrics
等都属于应用级别组件,因此仅允许配置单个实例;而 protocol
、registry
等允许配置多个的组件,在仅需要进行单例配置时,可采用此节描述的格式。常见示例如下:
dubbo.application.name=demo-provider
dubbo.application.qos-enable=false
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
针对某个实例的属性配置需要指定id或者name,其前缀格式为:配置类型复数前缀 + id/name。适用于 protocol
、registry
等支持多例配置的组件。
# 实例级配置(指定id或name)
dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
dubbo.{config-type}s.{config-name}.{config-item}={config-item-value}
配置示例:
dubbo.registries.unit1.address=zookeeper://127.0.0.1:2181
dubbo.registries.unit2.address=zookeeper://127.0.0.1:2182
dubbo.protocols.dubbo.name=dubbo
dubbo.protocols.dubbo.port=20880
dubbo.protocols.hessian.name=hessian
dubbo.protocols.hessian.port=8089
dubbo.service.org.apache.dubbo.samples.api.DemoService.timeout=5000
dubbo.reference.org.apache.dubbo.samples.api.DemoService.timeout=6000
方法配置格式:
# 方法配置
dubbo.service.{interface-name}.{method-name}.{config-item}={config-item-value}
dubbo.reference.{interface-name}.{method-name}.{config-item}={config-item-value}
# 方法argument配置
dubbo.reference.{interface-name}.{method-name}.{argument-index}.{config-item}={config-item-value}
方法配置示例:
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.timeout=7000
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.Oninvoke=notifyService.onInvoke
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.Onreturn=notifyService.onReturn
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.Onthrow=notifyService.onThrow
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.0.callback=true
等价于XML配置:
parameters参数为map对象,支持xxx.parameters=[{key:value},{key:value}]方式进行配置。
dubbo.application.parameters=[{item1:value1},{item2:value2}]
dubbo.reference.org.apache.dubbo.samples.api.DemoService.parameters=[{item3:value3}]
triple协议采用Http2做底层通信协议,允许使用者自定义Http2的6个settings参数
配置格式如下:
# 通知对端header压缩索引表的上限个数
dubbo.rpc.tri.header-table-size=4096
# 启用服务端推送功能
dubbo.rpc.tri.enable-push=false
# 通知对端允许的最大并发流数
dubbo.rpc.tri.max-concurrent-streams=2147483647
# 声明发送端的窗口大小
dubbo.rpc.tri.initial-window-size=1048576
# 设置帧的最大字节数
dubbo.rpc.tri.max-frame-size=32768
# 通知对端header未压缩的最大字节数
dubbo.rpc.tri.max-header-list-size=8192
等价于yml配置:
dubbo:
rpc:
tri:
header-table-size: 4096
enable-push: false
max-concurrent-streams: 2147483647
initial-window-size: 1048576
max-frame-size: 32768
max-header-list-size: 8192
可以将 xml 的 tag 名和属性名组合起来,用 ‘.’ 分隔。每行一个属性。
dubbo.application.name=foo
相当于
dubbo.registry.address=10.20.153.10:9090
相当于
如果在 xml 配置中有超过一个的 tag,那么你可以使用 ‘id’ 进行区分。如果你不指定id,它将作用于所有 tag。
dubbo.protocols.rmi.port=1099
相当于
dubbo.registries.china.address=10.20.153.10:9090
相当于
复数配置的命名与普通单词变复数的规则相同:
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 | 无 |
Dubbo 默认支持 6 种配置来源:
关于dubbo.properties属性:
-Ddubbo.properties.file=xxx.properties
。如果通过多种配置来源指定了相同的配置项,则会出现配置项的互相覆盖,具体覆盖关系和优先级请参考下一小节。
Dubbo 配置加载大概分为两个阶段:
属性覆盖是指用配置的属性值覆盖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. 指定id的实例级配置
dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
#2. 指定name的实例级配置
dubbo.{config-type}s.{config-name}.{config-item}={config-item-value}
#3. 应用级配置(单数配置)
dubbo.{config-type}.{config-item}={config-item-value}
属性覆盖处理流程:
按照优先级从高到低依次查找,如果找到此前缀开头的属性,则选定使用这个前缀提取属性,忽略后面的配置。
开启外部化配置后,registry、metadata-report、protocol、qos 等全局范围的配置理论上都不再需要在应用中配置,应用开发侧专注业务服务配置,一些全局共享的全局配置转而由运维人员统一配置在远端配置中心。
这样能做到的效果就是,应用只需要关心:
举例来说,每个应用中 Dubbo 相关的配置只有以下内容可能就足够了,其余的都托管给相应环境下的配置中心:
dubbo
application
name: demo
config-center
address: nacos://127.0.0.1:8848
所谓 Dubbo 对配置中心的支持,本质上就是把 .properties
从远程拉取到本地,然后和本地的配置做一次融合。理论上只要 Dubbo 框架能拿到需要的配置就可以正常的启动,它并不关心这些配置是自己加载到的还是应用直接塞给它的,所以Dubbo还提供了以下API,让用户将自己组织好的配置塞给 Dubbo 框架(配置加载的过程是用户要完成的),这样 Dubbo 框架就不再直接和 Apollo 或 Zookeeper 做读取配置交互。
// 应用自行加载配置
Map
dubboConfigurations.put("dubbo.registry.address", "zookeeper://127.0.0.1:2181");
dubboConfigurations.put("dubbo.registry.simplified", "true");
//将组织好的配置塞给Dubbo框架
ConfigCenterConfig cOnfigCenter= new ConfigCenterConfig();
configCenter.setExternalConfig(dubboConfigurations);
欢迎在 https://github.com/apache/dubbo 给 Dubbo Star。
搜索关注官方微信公众号:Apache Dubbo,了解更多业界最新动态,掌握大厂面试必备 Dubbo 技能