本文假设读者已阅读过《Apollo 官方 wiki 文档》,只对Client响应ConfigServer配置发布的细节进行分析。详情请前往《Apollo 官方 wiki 文档》
响应发布大致流程如下图,下面将从客户端响应ConfigServer配置发布和client启动Apollo监听两个模块讲解Apollo热发布原理。
1:当配置中心发布配置时,客户端响应流程
1:RemoteConfigLongPollService感知配置发布
RemoteConfigLongPollService通过长轮训(结合Spring DeferredResult)迅速感知配置发布,其通知RemoteConfigRepository到ConfigServer拉取最新配置。
1: 感知有配置发布
2:通知RemoteConfigRepository,向configServer发起同步配置请求
此处引入RemoteConfigLongPollService长轮训个人觉得是为了实现配置推送模式,apollo并不是使用消息来实现配置发布的推送
2:RemoteConfigRepository同步配置信息
RemoteConfigRepository相当于一个Apollo中的namespace。他即会定期主动到ConfigServer同步配置信息。也会由RemoteConfigLongPollService触发实时向ConfigServer同步配置。支持推拉两种同步配置的方式。
1:向ConfigServer同步配置数据
2:通知RepositoryChangeListener(处理配置更新的组件),有配置修改
3:启动定时任务,定时向ConfigServer同步配置
4:结合RemoteConfigLongPollService实时向ConfigServer同步配置数据,能够实时响应ConfigServer配置发布
思考:当RemoteConfigLongPollService感知到由配置发布时,他会将消息ID发送给RemoteConfigRepository由其发起同步消息内容的请求。此处为何不返回配置内容而是配置ID?
在github上咨询过作者,总结的答案是 详情 Apollo issue
1:实现幂等,应该是避免同一个配置发布被推和拉同时拿到吧。
2:逻辑清晰:RemoteConfigLongPollService只负责感知配置发布,RemoteConfigRepository负责同步数据。
3:RepositoryChangeListener、ConfigChangeListener负责处理配置发布事件
二者主要做的事情是
1:过滤出修改过的配置
2:更新修改配置的bean,
个人觉得二者可以合并,可以不用分的这么细。可能是作者为了更加灵活的配置。由于二者只是将更改的配置传递,所以没有贴出源码。
4:AutoUpdateConfigChangeListener.onChange() 实现配置热发布
1:通过SpringValueRegistry(管理所有需要注入配置的bean,下文有详细介绍) 去修改拥有配置信息的bean
2:触发bean更新配置
总结:
1:RemoteConfigLongPollService、RemoteConfigRepository、RepositoryChangeListener、ConfigChangeListener四者层级关系在启动时由@EnableApolloConfig触发,通过集合维护下层对象。
2:RemoteConfigLongPollService、RemoteConfigRepository内部结合线程池和Spring DeferredResult实现了配置推拉结合的模式是亮点。并没有借助于消息队列中间件。
2:客户端启动搭建监听流程
1:@EnableApolloConfig,启动apollo配置中心,
具体初始化操作有ApolloConfigRegistrar完成。
2:PropertySourcesProcessor Spring容器预处理器
1:从配置中心拉去配置到项目环境
2:添加配置修改监听器,使得配置中心实现热发布
3:ApolloAnnotationProcessor Spring容器预处理器
1:完成ApolloConfig标注属性的赋值
2:完成ApolloConfigChangeListener标注的配置更改监听事件
4:SpringValueProcessor Spring容器预处理器
将需要动态配置的bean由SpringValueRegistry统一管理,以便配置实现热发布时,可以动态的更改配置。
5:SpringValueDefinitionProcessor 处理有xml的配置类
6:ApolloProcessor 处理json To Object
总结:
以上操作结合Spring容器的高级特性,比如预处理器BeanPostProcessor实现Client读取配置和监听配置更改。
包菜:SPRING容器高级特性zhuanlan.zhihu.com
3:Apollo整体架构图
来源:oschina
链接:https://my.oschina.net/xiaominmin/blog/3167443