在Dubbo 2中,属性配置与dubbo-spring-boot外部化配置的功能存在重叠,规则不清晰,在API配置、Spring XML配置、Java-config配置等不同场景下存在比较多的问题。
Dubbo 3对属性配置进行重新梳理,明确属性配置覆盖的规则,并融合外部化配置功能,贯通API配置、Spring XML配置、Java-config配置等不同场景。
属性配置覆盖
属性配置覆盖是指用配置属性值覆盖config实例的字段值,类似Spring PropertyOverrideConfigurer
的作用。
属性配置格式优先级(由高到低)如下:
#格式1 指定实例id的属性配置:复数前缀+config-id
dubbo.{config-type}s.{config-id}.{config-item}={config-item-value}
#格式2 指定实例name的属性配置:复数前缀+config-name (没有name属性时忽略此项)
dubbo.{config-type}s.{config-name}.{config-item}={config-item-value}
#格式3 单数配置(匿名实例配置):单数前缀
dubbo.{config-type}.{config-item}={config-item-value}
属性覆盖时,依照上面的次序查找匹配的属性,如果存在该种格式的属性,则选定此前缀来提取属性集合,其它的格式的配置将被忽略。举例说明:
@Configuration
public class DubboConfig {
@Bean
public ProtocolConfig protocolConfig(){
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setId("my-protocol");
protocolConfig.setName("dubbo");
return protocolConfig;
}
}
上面的ProtocolConfig属性覆盖查找顺序:
(1) 其id为"my-protocol", 尝试查找带id的配置: dubbo.protocols.my-protocol.xxx=xxx
(2) 如果没有找到匹配的属性配置,则继续找带name的配置(其name为"dubbo"):dubbo.protocols.dubbo.xxx=xxx
(3) 如果没有找到匹配的属性配置,则继续找单数配置:dubbo.protocol.xxx=xxx
注意: 按优先级高到低查找属性配置,如果找到匹配的属性配置,则使用此前缀打头的一组属性,不会再使用后面的格式。可以参照SpringBoot ConfigurationProperties的prefix来理解,不同的是Dubbo属性配置的prefix不是固定的,而是从多个prefix中选择存在的最高优先级的prefix。
外部化配置
外部化配置是指将DubboBootstrap API/Spring XML/Java-config等方式的config配置改为通过属性配置,即从配置属性生成config实例,类似SpringBoot ConfigurationProperties的作用。
下面是配置样例:
# application
dubbo.application.name=demoapp
# protocol
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
# registry
dubbo.registry.address=zookeeper://10.10.10.1:2181
# config-center
dubbo.config-center.address=zookeeper://10.10.10.2:2181
# consumer
dubbo.consumer.check=false
多实例的配置样例:
#多个registry
dubbo.registries.register1.address=zookeeper://10.10.10.1:2181
dubbo.registries.register2.address=zookeeper://10.10.10.2:2181
#多个protocol
dubbo.protocols.dubbo.port=20881
dubbo.protocols.rest.port=8080
注意:Dubbo 3在内核支持了外部化配置功能,在非SpringBoot环境也可以正常使用。
属性配置覆盖 VS 外部化配置:
(1) 外部化配置创建config实例时会检查是否存在相同id的config实例,如果不存在则创建,否则按照属性配置覆盖逻辑刷新原config实例的值;
(2) 只有不存在某种类型的config实例时,才会根据单数配置创建config实例。
服务接口的配置
service 和reference的配置格式有所不同,按照下面的格式:
# 服务接口配置
dubbo.service.{interfaceName}.{item}={value}
dubbo.reference.{interfaceName}.{item}={value}
# 接口的方法配置
dubbo.service.{interfaceName}.{methodName}.{item}={value}
dubbo.reference.{interfaceName}.{methodName}.{item}={value}
如DemoService接口的配置:
# 服务接口配置
dubbo.service.org.apache.dubbo.demo.DemoService.timeout=500
dubbo.reference.org.apache.dubbo.demo.DemoService.check=false
# 接口的方法配置
dubbo.service.org.apache.dubbo.demo.DemoService.sayHello.timeout=500
dubbo.reference.org.apache.dubbo.demo.DemoService.sayHello.retries=3
单复数配置对照表
复数配置的命名与普通单词变复数的规则相同:
(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 | 无 |
注意:service/reference的配置格式与其它不一样,为单数前缀+接口名。
忽略的字段
Config的一些字段是内部使用,不能被配置的属性覆盖,刷新属性时会被忽略掉。
如:refreshed、valid、inited、prefixes、parentPrefix等,详细列表请查看org.apache.dubbo.config.AbstractConfig#IGNORED_ATTRIBUTES。
案例分析
为了更透彻理解属性配置覆盖的功能,下面用几个例子进行分析说明。
下面几个例子都使用一份属性配置:
# default protocol config
dubbo.protocol.name=dubbo
dubbo.protocol.port=20883
# protocol config of name=dubbo
dubbo.protocols.dubbo.port=20881
# protocol config of id=my-protocol
dubbo.protocols.my-protocol.name=dubbo
dubbo.protocols.my-protocol.port=20881
例子1(DubboBootstrap API):
DubboBootstrap.getInstance()
...
.protocol(new ProtocolConfig())
...
这里添加了一个空白的ProtocolConfig实例,没有设置id和name,根据上面的配置格式优先级,只能使用配置格式3(单数配置),如 dubbo.protocol.xxx=xxx
。
#default protocol config
dubbo.protocol.name=dubbo
dubbo.protocol.port=20883
例子2(Spring XML):
<dubbo:protocol name="dubbo" port="20813"/>
这里通过XML定义了一个Protocol,并指定了name="dubbo",刚好匹配上配置格式2(带name的配置)。
# protocol config of name=dubbo
dubbo.protocols.dubbo.port=20881
例子3(Spring Java-config):
@Configuration
public class DubboConfig {
@Bean("my-protocol")
public ProtocolConfig protocolConfig(){
return new ProtocolConfig();
}
}
这里定义了一个ProtocolConfig 的bean,没有在代码中指定id。当config id为空时,Dubbo会在BeanPostProcessor中将beanName设置为config实例的id。 根据上面的配置格式优先级,会优匹配带id的配置属性(dubbo.protocols.my-protocol.xxx=xxx)。
# protocol config of id=my-protocol
dubbo.protocols.my-protocol.name=dubbo
dubbo.protocols.my-protocol.port=20881
例子4:
@Configuration
public class DubboConfig {
@Bean
public ProtocolConfig protocolConfig(){
return new ProtocolConfig("dubbo");
}
}
这个例子与例子3的区别是ProtocolConfig的beanName为protocolConfig,会将其设置为ProtocolConfig的id。另外一个区别是设置是协议名称为"dubbo"。
属性查找过程:
1)尝试查找带id的属性:dubbo.protocols.protocolConfig.xxx=xxx,但没有找到这类属性;
2)尝试查找带name的属性:dubbo.protocols.dubbo.xxx=xxx,匹配上了第2组配置[protocol config of name=dubbo]
# protocol config of name=dubbo
dubbo.protocols.dubbo.port=20881
例子5:
<dubbo:protocol name="rest" port="8080"/>
属性查找过程:
1)这个例子的protocol指定name,但没有id(自动生成的beanName不会设置为config id,不会用于属性匹配);
2)查找带name的属性配置: dubbo.protocols.rest.xxx=xxx,但没有找到这种属性;
3)最后查找单数属性配置:dubbo.protocol.xxx=xxx
#default protocol config
dubbo.protocol.name=dubbo
dubbo.protocol.port=20883
1条答案
按热度按时间6tdlim6h1#
After Dubbo3.0, we need to provide a more comprehensive configuration description.
apache/dubbo-website#970