一、Config Server和Client原理
备注:Spring Cloud Config和Spring Cloud Eurake相似,都有客户端和服务端。
1、ConfigServer(配置中心服务端)从远端git拉取配置文件并在本地git一份,ConfigClient(微服务)从ConfigServer端获取自己对应 配置文件;
2,、手动刷新?
通过actuator和@RefreshScope通过调用actuator/refresh
3、当远端git仓库配置文件发生改变,ConfigServer如何通知到ConfigClient端,即ConfigClient如何感知到配置发生更新?
Spring Cloud Bus会向外提供一个http接口,即图中的/bus/refresh。我们将这个接口配置到远程的git的webhook上,当git上的文件内容发生变动时,就会自动调用/bus-refresh接口。Bus就会通知config-server,config-server会发布更新消息到消息总线的消息队列中,其他服务订阅到该消息就会信息刷新,从而实现整个微服务进行自动刷新。
1、提交配置触发post请求给server端的bus/refresh接口
2、server端接收到请求并发送给Spring Cloud Bus总线
3、Spring Cloud bus接到消息并通知给其它连接到总线的客户端
4、其它客户端接收到通知,请求Server端获取最新配置
5、全部客户端均获取到最新的配置
二、Spring Boot配置文件加载过程
我们可以从SpringApplication.run()方法作为入口,prepareEnvironment是一个比较关键的方法;可以看出在Run方法中是,先加载PrepareEnvironment准备环境,然后在去准备Context上下文
1,PrepareEnvironment中getOrCreateEnvironment是根据WebApplication的类型选择不同的Environment,
接着再点进去**getOrCreateEnvironment()**中去,根据不同的特点,选择不同的环境
我们根据不同的环境选择不同的Environment;StandardServletEnvironment是整个spring boot应用运行环境的实现类,后面所有的关于环境相关的配置操作都是基于这个类。StandardEnvironment是StandardServletEnvironment的父类,AbstarctEnvironment是StandardEnvironment的父类,StandardServletEnvironment 中customizePropertySources的作用及时将不同配置源封装成PropertySource添加到MutablePropertySources中,调用AddLast标志一直往最后的位置添加。StandardServletEnvironment.customizePropertySources()中添加了servlet配置信息和servlet初始上下文信息,JNDI信息;接着调用其父类StandardEnvironment.customizePropertySources来添加系统的变量和系统的环境变量。
接着是configureEnvironment方法,这个方法中给Environment中添加类型转化的服务,property都是String类型的,转换为java对象需要根据合适的类型进行转化;配置当前激活的Profiles;configurePropertySources根据是否加载参数添加不同的propertySource。
listeners.environmentPrepared(environment);
上述工作完成之后,就是发布一个environmentPrepared环境准备就绪的通知,具体的时间监听过程的代码就不再分析了,我们直接进入到 ConfigFileApplicationListener 这个监听器,这个监听器就是用来处理项目配置的
配置加载过程:
ConfigFileApplicationListener.onApplicationEvent 收到事件之后,最终执行到ConfigFileApplicationListener.addPropertySources 方法中;这个方法做了两件事情,添加一个RandomValuePropertySource到Environment的MutablePropertySources中
加载spring boot中的配置信息,比如application.yml或者application.properties
至此,springBoot中的资源文件加载完毕,解析顺序从上到下,所以前面的配置文件会覆盖后面的配置
文件。可以看到 application.properties 的优先级最低,系统变量和环境变量的优先级相对较高。
三、Config Client 配置加载过程
从上边Spring boot的加载过程,可以推测;Config Client配置加载也一定与spring的某个机制有关系。
在spring boot项目启动时,有一个prepareContext的方法,它会回调所有实现了ApplicationContextInitializer 的实例,来做一些初始化工作。
PropertySourceBootstrapConfiguration 实现了 ApplicationContextInitializer 接口,其目的就是在应用程序上下文初始化的时候做一些额外的操作.
回调所有实现PropertySourceLocator接口实例的locate方法;最终调用ConfigServicePropertySourceLocator.locate();它会通过RestTemplate调用一个远程地址获得配置信息,
getRemoteEnvironment 。然后把这个配置PropertySources,然后将这个信息包装成一个
OriginTrackedMapPropertySource,设置到 Composite 中。
四、Config Server获取配置过程
服务器端去远程仓库加载配置的流程就比较简单了,核心接口是: EnvironmentRepository
Spring Cloud Config Server提供了EnvironmentController,这样通过在浏览器访问即可从git中获取配
置信息
在这个controller中,提供了很多的映射,最终会调用的是 getEnvironment 。
this.repository.findOne ,调用某个repository存储组件来获得环境配置信息进行返回。
repository是一个 EnvironmentRepository 对象,它有很多实现,其中就包含
RedisEnvironmentRepository 、 JdbcEnvironmentRepository 等。默认实现是
MultipleJGitEnvironmentRepository ,表示多个不同地址的git数据源。