Dubbo 2.6.2 获取不到${dubbo.registry.address}

在将应用配置从闭源系统迁移到k8s configMap的过程中,遇到一个问题:Dubbo 2.6.2无法获取${dubbo.registry.address}配置。通过源码分析发现,Dubbo不是从Spring的PropertySource获取配置,而是从环境变量或配置文件。解决方案包括手动创建Spring Bean,设置系统环境变量,或者升级到2.7.6及以上版本。

背景

公司原来的配置中心是一个闭源的系统,该系统有几个痛点问题:无权限控制、敏感配置不能加密、应用和配置的依赖关系混乱。
在这个背景下,运维同学基于k8s的configMap写了一个配置中心,并推动应用配置从闭源的配置中心迁移到自有的configMap。

获取dubbo.registry.address配置项

因为我负责这次迁移,所以迁移过程中开发同学碰到的问题都会来问我,其中有一个比较有意思的问题是dubbo 获取不到dubbo.registry.address配置项。比如明明在application.properties配置文件中配置了该配置项 dubbo.registry.address=zk-0:2181,但应用启动时就是获取不到;

源码

此类问题排查思路也比较直接:直接看源码!

通过debug,很快定位到dubbo.registry.address是在AbstractInterfaceConfig.java 第188行获取配置的。
获取配置

突然发现有点不太对劲,怎么获取配置的这个方式是静态方案?!难道没有和spring的PropertySource打通?

点进去该方法果然发现,这里的配置并不是从spring的PropertySource中获取的,而是尝试从系统环境变量中获取,获取不到再从配置的文件中获取。参考com.alibaba.dubbo.common.utils.ConfigUtils#getProperty(java.lang.String, java.lang.String)

获取配置
这时候真相大白了,人家压根就没有去application.properties中获取,那肯定就拿不到了。

后面想看看dubbo对这个问题进行处理,于是乎打开了2.7.6版本的源码瞅了瞅。在这个版本中,dubbo变成了从spring中获取配置的方式。感兴趣的小伙伴可以看看相关的源码,这里就不展开了。

从Spring PropertySource中获取

解法

  1. 手动配置一个RegistryConfig Spring Bean;
  2. 将dubbo相关配置设置到系统环境变量中;
  3. 升级到2.7.6。

扫码关注,一起进步

Java 应用中,`java.lang.IllegalArgumentException` 是一个常见的运行时异常,表示传递给方法的参数不合法或不符合预期。具体到 Dubbo 配置中,当遇到 `IllegalArgumentException` 并提示无法解析占位符 `${dubbo.fmds.register.address}` 时,问题通常与配置属性的加载或占位符解析机制有关。 ### 异常原因分析 1. **属性未定义或未加载** 占位符 `${dubbo.fmds.register.address}` 表示从配置文件(如 `application.properties` 或 `application.yml`)中读取对应的值。如果该属性未被定义,或在 Spring 容器启动时未正确加载,将导致解析失败,进而抛出 `IllegalArgumentException`。 2. **配置文件路径问题** 如果配置文件未放置在类路径(classpath)下,或未被 Spring Boot 正确识别,属性将无法加载。确保 `application.properties` 或 `application.yml` 文件位于 `src/main/resources` 目录下。 3. **Spring Boot 占位符解析机制问题** Spring Boot 使用 `PropertySourcesPlaceholderConfigurer` 来解析 `${}` 占位符。如果该配置未正确注册,或在 Dubbo 配置加载时属性尚未解析,也可能导致异常。 4. **Spring Boot DevTools 影响** 在某些情况下,如引用[2]所述,`spring-boot-devtools` 可能影响类加载机制,导致属性解析失败。如果使用了该依赖,可尝试移除它以排查是否与此相关[^2]。 --- ### 解决方案 1. **确认属性定义** 确保在 `application.properties` 或 `application.yml` 中定义了 `dubbo.fmds.register.address` 属性。例如: ```properties dubbo.fmds.register.address=zookeeper://192.168.1.100:2181 ``` 2. **检查属性加载顺序** Dubbo 配置可能在 Spring 属性加载完成前被解析,导致占位符无法识别。可以通过自定义 `PropertySourcesPlaceholderConfigurer` 来确保属性在 Dubbo 初始化前被正确加载: ```java @Configuration public class PropertyConfig { @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } } ``` 3. **使用 `@Value` 注解注入属性** 在 Dubbo 配置类中,使用 `@Value` 注解注入占位符值,确保属性在运行时正确解析: ```java @Service public class DubboConfig { @Value("${dubbo.fmds.register.address}") private String registerAddress; // 使用 registerAddress 配置 Dubbo 注册中心 } ``` 4. **避免使用 `spring-boot-devtools`** 如果项目中使用了 `spring-boot-devtools`,尝试移除该依赖,以排除其对类加载和属性解析的干扰。 5. **使用 `Environment` 获取属性值** 在 Dubbo 配置类中注入 `Environment` 对象,并通过其获取属性值,确保属性已加载: ```java @Autowired private Environment env; String registerAddress = env.getProperty("dubbo.fmds.register.address"); ``` --- ### 示例:完整配置类 ```java @Configuration public class DubboConfiguration { @Value("${dubbo.fmds.register.address}") private String registerAddress; @Bean public ApplicationConfig applicationConfig() { ApplicationConfig application = new ApplicationConfig(); application.setName("demo-provider"); return application; } @Bean public RegistryConfig registryConfig() { RegistryConfig registry = new RegistryConfig(); registry.setAddress(registerAddress); registry.setRegister(true); return registry; } } ``` --- ### 总结 `java.lang.IllegalArgumentException` 在 Dubbo 中通常与属性解析失败有关,尤其是在使用 `${}` 占位符时。通过确保属性定义正确、加载顺序合理以及合理使用 `@Value` 或 `Environment` 注入属性,可以有效解决此类问题。此外,`spring-boot-devtools` 的存在可能干扰属性解析流程,必要时可尝试移除该依赖。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值