Spring3.0.5集成Apollo分布式配置中心

需求

GitHub地址:https://github.com/ctripcorp/apollo/wiki/Apollo配置中心介绍#32-界面概览
实际上大多数人的文章都是copy的这个,没有任何参考意义. 没有一点自己的东西.

文章说只支持Spring3.1.1以上. 由于我们项目比较老. 用的还是Spring3.0.5,现在项目需要集成分布式配置中心,之前考虑过Spring Cloud Config,发现旧的Spring版本集成有很大的冲突.不太适合. 所以考虑选择携程Apollo.
话不多说. 上代码.

2.1 引入依赖

<dependency>
	<groupId>com.ctrip.framework.apollo</groupId>
	<artifactId>apollo-client</artifactId>
	<version>1.4.0</version>
</dependency>

2.2 新建配置文件

resource目录下新建目录META-INF,然后新建配置文件app.properties

apollo.meta=http://192.168.13.34:8080 
env=DEV
app.id=demo-module
apollo.bootstrap.enabled=true

注: 这些参数都可以放到JVM启动参数里. 后续用Docker部署会使用到.

获取配置的方式,除了SpringBoot的注解方式,还有ConfigService.getConfig()

Config apolloConfig = ConfigService.getAppConfig();
String value = apolloConfig.getProperty("key", "defaultValue");

实际上Apollo除了配置属性,还有实时更新,以及灰度发布功能,这个才是亮点. 下面就讲讲我的踩坑记录.

集成完上面之后启动工程.OK,获取到配置,动态获取OK,完美. 但是如何做到配置修改动态更新?
查看github的帮助文档.直接增加一个listener即可.

扩展下Apollo动态更新配置的原理:线程池里启动一个Http的长连接,每个实例都有. 如果配置发生了变化,则与本地的配置的文件作比较. 然后更新到JVM里.

代码如下:

// 获取阿波罗的配置信息
Config apolloConfig = ConfigService.getAppConfig();

// 注册参数变更监听
apolloConfig.addChangeListener(new ConfigChangeListener() {
	@Override
	public void onChange(ConfigChangeEvent configChangeEvent) {
		for (String key : configChangeEvent.changedKeys()) {
			ConfigChange change = configChangeEvent.getChange(key);
			System.out.println(String.format(
					"Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s",
					change.getPropertyName(), change.getOldValue(),
					change.getNewValue(), change.getChangeType()));
			System.setProperty(String.valueOf(key), String.valueOf(change.getNewValue()));
		}
	}
});

那么现在在界面上修改配置,并且发布之后,本地理论上就可以收到变更.

再扩展下是如何实现的:Apollo分为三个模块. Portal负责界面的操作. AdminService负责与Portal交互,做一些配置的增删改查,ConfigService负责与客户端通信,负责推送和获取配置.当配置发送变更后, Portal点击发布后,AdminService会发布一个消息给ConfigService
c.c.f.a.b.message.DatabaseMessageSender : Sending message appId+default+application to channel apollo-release, 然后客户端通过轮询的方式来获取ConfigService获取最新的配置.

然而事实总是很残酷.按照官方的配置后,果然没有自动更新.果断看源码是如何实现的.
至于具体的调试步骤不详细写了。
最后定位到是DefaultConfig.updateAndCalcConfigChanges方法里的170行有问题
在这里插入图片描述
注意看这里的setNewValue,实际上chane里已经包含了新值和旧值,不清楚作者为何还要去通过getProperty再次获取.
问题就在于这个step1, 如果工程启动的时候我将所有属性全部加入到System中之后,如果再有变更,这个方法里永远返回的是旧值. 实际上此时的step2里的m_configProperties里已经是新值了. 所以就覆盖了change对象里的newValue,导致和oldValue一致了。然后后面判断即没有变化,自然就不会调用我们的listener了.
在这里插入图片描述
针对此问题已经向宋大佬提问了。还未回复

Github的提问:https://github.com/ctripcorp/apollo/issues/2501

个人理解这里实际上不需要再去getProperty的。直接使用change对象里的。
本地修改源码后.去掉
在这里插入图片描述
然后再启动测试参数实时更新正常.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值