撸了一个简易的配置中心,顺带整合到了SpringCloud( 二 )


至于前面说的配置文件变更通知的功能,我是基于客户端来实现的 。
三、客户端的实现客户端工程代码如下

撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
1、ConfigFileChangedListener
撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
ConfigFileChangedListener
配置变动的监听器 , 当客户端对某个配置监听的时候,如果这个配置的内容有变化的话 , 客户端就会回调这个监听器 , 传入最新的配置
2、ConfigService
撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
封装了客户端的核心功能,可以添加对某个文件的监听器和获取某个文件的配置内容 。
使用示例:
// 创建一个ConfigService,传入配置中心服务端的地址ConfigService configService = new ConfigService("localhost:8888");// 从服务端获取配置文件的内容,文件的id是新增配置文件时候自动生成ConfigFile config = configService.getConfig("69af6110-31e4-4cb4-8c03-8687cf012b77");// 对某个配置文件进行监听configService.addListener("69af6110-31e4-4cb4-8c03-8687cf012b77", new ConfigFileChangedListener() {    @Override    public void onFileChanged(ConfigFile configFile) {        System.out.printf("fileId=%s配置文件有变动,最新内容为:%s%n", configFile.getFileId(), configFile.getContent());    }});这里说一下配置变更通知的实现原理 。
首先对于客户端来说,要想知道哪个配置文件进行了改动,有两种方式
第一种是通过push的方式来实现 。当配置文件发生变动的时候,服务端主动将变动的配置文件push给客户端 。这种方式实现起来比较麻烦,一方面是服务端还得存储客户端的服务的信息 , 因为服务端得知道push到哪台服务器上;另一方面,客户端需要提供一个接口来接收服务端push的请求,所以这种方式整体实现起来比较麻烦 。但是这种push方式时实性比较好 , 一旦配置文件有变动,第一时间客户端就能够知道配置有变动 。
第二种方式就是基于pull模式来实现 。客户端定时主动去服务端拉取配置文件,判断文件内容是否有变动 , 一旦有变动就进行监听器的回调 。这种实现相比push来说简单不少,因为服务端不需要关心客户端的信息,所有的操作都由客户端来完成 。但是这个定时的时间间隔不好控制 , 太长可能会导致时实性差,太短会导致可能无效请求过多,因为配置压根可能没有变化 。
但是这里我选择了第二种方式,因为实现起来简单 。。

撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
变动通知代码实现
到这,一个简单的配置中心的服务端的和客户端就完成了,这里画张图来总结一下配置中心的核心原理 。

撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
接下来就把这个简易的配置中心整合到SpringCloud中 。
SpringCloud配置中心的原理1、项目启动是如何从配置中心加载数据的?在SpringCloud环境下,当项目启动的时候 , 在SpringBoot应用容器创建之前,会先创建一个容器,这个容器非常重要,这个容器是用来跟配置中心交互,拉取配置的 。
这个容器在启动的时候会干两件事:
  • 加载bootstrap配置文件,这就是为什么配置中心的配置信息需要写在bootstrap配置文件的重要原因
  • 加载所有spring.factories文件中的键为org.springframework.cloud.bootstrap.BootstrapConfiguration对应的配置类 , 将这些配置类注入到这个容器中,注意这里是不会加载@EnbaleAutoConfiguration自动装配的类
当这两件事都做好之后,会从这个容器中获取到所有的PropertySourceLocator这个接口的实现类对象 , 依次调用locate方法 。

撸了一个简易的配置中心,顺带整合到了SpringCloud

文章插图
PropertySourceLocator
这个类很重要 , 先来看看注释
Strategy for locating (possibly remote) property sources for the Environment. Implementations should not fail unless they intend to prevent the application from starting.
扔到有道翻译如下:
为环境定位(可能是远程)属性源的策略 。实现不应该失败,除非它们打算阻止应用程序启动 。

推荐阅读