关于dubbo-spring-boot-starter处理Multiple配置的疑问 - Go语言中文社区

关于dubbo-spring-boot-starter处理Multiple配置的疑问


问题简述
使用dubbo-spring-boot-starter无法正确处理多 Dubbo 配置,而原始dubbo可以正确处理

多 Dubbo 配置 Bean 绑定

以下描述摘自Dubbo 外部化配置(Externalized Configuration)

Dubbo @Service@Reference 允许 Dubbo 应用关联ApplicationConfig Bean 或者指定多个RegistryConfig Bean 等能力。换句话说,Dubbo 应用上下文中可能存在多个ApplicationConfig 等 Bean定义。
为了适应以上需要,因此从Dubbo 2.5.9 开始,@EnableDubboConfig 支持多 Dubbo 配置 Bean 绑定,同时按照业界规约标准,与单 Dubbo 配置 Bean 绑定约定不同,配置属性前缀均为英文复数形式:
详情请参考 :https://github.com/alibaba/dubbo/issues/1141

  • dubbo.applications
  • dubbo.modules
  • dubbo.registries
  • dubbo.protocols
  • dubbo.monitors
  • dubbo.providers
  • dubbo.consumers

使用使用官方https://github.com/apache/dubbo-spring-boot-project
提供的dubbo-spring-boot-starter实践上述配置时会出现一些问题。而使用原始dubbo能正常处理。现描述如下,也请业界大佬帮忙解答是否为bug,亦或另有深意。

问题复现

maven配置

1. 原始dubbo依赖配置

<properties>
    <spring-boot.version>2.1.6.RELEASE</spring-boot.version>
    <dubbo.version>2.7.3</dubbo.version>
</properties>
...
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
	<version>${spring-boot.version}</version>
</dependency>

<dependency>
	<groupId>org.apache.dubbo</groupId>
	<artifactId>dubbo</artifactId>
	<version>${dubbo.version}</version>
</dependency>

2. 使用dubbo-spring-boot-starter依赖配置

<properties>
    <spring-boot.version>2.1.6.RELEASE</spring-boot.version>
    <dubbo.version>2.7.3</dubbo.version>
</properties>
...
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
	<version>${spring-boot.version}</version>
</dependency>

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>${dubbo.version}</version>
</dependency>

第一个问题

使用dubbo-spring-boot-starter处理如下配置

dubbo.consumers.user.application.name=consumers-user-application
dubbo.consumers.web.application.name=consumers-web-application

会报错:

Failed to bind properties under 'dubbo.consumers.web' to org.apache.dubbo.config.ConsumerConfig:

    Reason: Duplicate Config found for ApplicationConfig, you should use only one unique ApplicationConfig for one application.

分析说明

原始dubbo与dubbo-spring-boot-starter处理dubbo.consumers.*的异同代码说明
1. 原始dubbo使用org.apache.dubbo.config.spring.context.properties.DefaultDubboConfigBinder处理配置绑定。而dubbo-spring-boot-starter使用org.apache.dubbo.spring.boot.autoconfigure.BinderDubboConfigBinder。如下图:

  • 原始dubbo
    image.png
  • dubbo-spring-boot-starter
    image.png

2. 处理ConsumerConfig配置的异同

配置ConsumerConfig时会调用ConsumerConfig父类AbstractInterfaceConfig#setApplication方法配置ApplicationConfig。此时会使用org.apache.dubbo.config.context.ConfigManager#checkDuplicate对Application配置做重复校验。

  • 关键在此,原始dubbo方案配置ConsumerConfig时,对其私有ApplicationConfig只做了初始化而没有配置属性。所以处理以下配置时
dubbo.consumers.user.application.name=consumers-user-application
dubbo.consumers.web.application.name=consumers-web-application

根据org.apache.dubbo.config.context.ConfigManager#checkDuplicate的处理逻辑始终都具有唯一性,从而正常校验通过。详细参考源码。

  • 而使用dubbo-spring-boot-starter配置ConsumerConfig时,其私有的ApplicationConfig已完成了初始化和属性配置。所以当有多个dubbo.consumers.*.application.*配置时,org.apache.dubbo.config.context.ConfigManager#checkDuplicate校验第二ConsumerConfig的ApplicationConfig时就会失败,从而报错。

以上说明的代码跟踪截图如下:

  • 原始dubbo

第1次处理"dubbo.consumers.user.application.name=consumers-user-application",正常通过

image.png

image.png

第2次处理"dubbo.consumers.web.application.name=consumers-web-application",同样正常通过

image.png

  • dubbo-spring-boot-starter
    第1次处理"dubbo.consumers.user.application.name=consumers-user-application",正常通过,因为ConfigManager是单例调用,第一次调用时,内部属性application为null。

image.png

image.png

第2次处理"dubbo.consumers.web.application.name=consumers-web-application",失败报错。因为此时调用ConfigManager时,内部属性application保留了第一次调用时的application,且有完整的属性,所以调用checkDuplicate方法时报错。

image.png

其它类似dubbo.(*s).*.application.*配置同样会包类似的错误

第二个问题

使用dubbo-spring-boot-starter处理如下配置

dubbo.applications.app1.name=applications-app1
dubbo.applications.app2.name=applications-app1

会报错:


java.lang.IllegalStateException: There are more than one instances of ApplicationConfig, whose bean definitions : [Root bean: class [org.apache.dubbo.config.ApplicationConfig]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, Root bean: class [org.apache.dubbo.config.ApplicationConfig]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
...
...

分析说明

dubbo-spring-boot-starter处理dubbo配置时,使用了org.apache.dubbo.spring.boot.beans.factory.config.DubboConfigBeanDefinitionConflictProcessor类处理ApplicationConfig配置冲突。
分析源码后,很费解其处理逻辑,根据逻辑,完全就排斥dubbo.applications.*的配置。
代码跟踪截图如下:

image.png

第三个问题

org.apache.dubbo.config.AbstractConfig#equals方法中为什么Exception情况下会返回true。
image.png

官方资料参考

关于多 Dubbo 配置 Bean 绑定,官方可参考的资源如下:

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/zkq1989/article/details/102742887
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-06-27 21:57:18
  • 阅读 ( 1160 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢