Dubbo 3 属性配置说明

tjvv9vkg  于 2023-02-04  发布在  其他
关注(0)|答案(1)|浏览(147)

在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单数配置复数配置
applicationdubbo.application.xxx=xxxdubbo.applications.{id}.xxx=xxx
dubbo.applications.{name}.xxx=xxx
protocoldubbo.protocol.xxx=xxxdubbo.protocols.{id}.xxx=xxx
dubbo.protocols.{name}.xxx=xxx
moduledubbo.module.xxx=xxxdubbo.modules.{id}.xxx=xxx
dubbo.modules.{name}.xxx=xxx
registrydubbo.registry.xxx=xxxdubbo.registries.{id}.xxx=xxx
monitordubbo.monitor.xxx=xxxdubbo.monitors.{id}.xxx=xxx
config-centerdubbo.config-center.xxx=xxxdubbo.config-centers.{id}.xxx=xxx
metadata-reportdubbo.metadata-report.xxx=xxxdubbo.metadata-reports.{id}.xxx=xxx
ssldubbo.ssl.xxx=xxxdubbo.ssls.{id}.xxx=xxx
metricsdubbo.metrics.xxx=xxxdubbo.metricses.{id}.xxx=xxx
providerdubbo.provider.xxx=xxxdubbo.providers.{id}.xxx=xxx
consumerdubbo.consumer.xxx=xxxdubbo.consumers.{id}.xxx=xxx
servicedubbo.service.{interfaceName}.xxx=xxx
referencedubbo.reference.{interfaceName}.xxx=xxx
methoddubbo.service.{interfaceName}.{methodName}.xxx=xxx dubbo.reference.{interfaceName}.{methodName}.xxx=xxx
argumentdubbo.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
6tdlim6h

6tdlim6h1#

After Dubbo3.0, we need to provide a more comprehensive configuration description.
apache/dubbo-website#970

相关问题