大家好,这篇文章跟大家聊下 SpringCloudAlibaba 中的微服务组件 Nacos。Nacos 既能做注册中心,又能做配置中心,这篇文章主要来聊下做配置中心时 client 端的一些设计,主要从源码层面进行分析,相信看完这篇文章你对 Nacos client 端的工作原理应该有比较深刻的了解。
SpringCloud 应用启动拉去配置
我们之前写过一篇文章,介绍了一些 Spring 提供的扩展机制。其中说到了 ApplicationContextInitializer,该扩展是在上下文准备阶段(prepareContext),容器刷新之前做一些初始化工作,比如我们常用的配置中心 client 基本都是继承该初始化器,在容器刷新前将配置从远程拉到本地,然后封装成 PropertySource 放到 Environment 中供使用。
在 SpringCloud 场景下,SpringCloud 规范中提供了 PropertySourceBootstrapConfiguration 继承 ApplicationContextInitializer,另外还提供了个 PropertySourceLocator,二者配合完成配置中心的接入。
从上述截图可以看出,在 PropertySourceBootstrapConfiguration 这个单例对象初始化的时候会将 Spring 容器中所有的 PropertySourceLocator 实现注入进来。然后在 initialize 方法中循环所有的 PropertySourceLocator 进行配置的获取,从这儿可以看出 SpringCloud 应用是支持我们引入多个配置中心实现的,获取到配置后调用 insertPropertySources 方法将所有的 PropertySource(封装的一个个配置文件)添加到 Spring 的环境变量 environment 中。
上图展示了在 spring-cloud-starter-alibaba-nacos-config 包提供的自动装配类中进行了 NacosPropertySourceLocator 的定义,该类继承自上述说的 PropertySourceLocator,重写了 locate 方法进行配置的读取。
我们来分析下 NacosPropertySourceLocator,locate 方法只提取了主要流程代码,可以看到 Nacos 启动会加载以下三种配置文件,也就是我们在 bootstrap.yml 文件里配置的扩展配置 extension-configs、共享配置 shared-configs 以及应用自己的配置,加载到配置文件后会封装成 NacosPropertySource 返回。
public PropertySource<?> locate(Environment env) {
|
|
// 生成 NacosConfigService 实例,后续配置操作都是围绕该类进行 |
|
ConfigService configService = nacosConfigManager.getConfigService(); |
|
if (null == configService) {
|
|
log.warn("no instance of config service found, can't load config from nacos"); |
|
return null; |
|
} |
|
long timeout = nacosConfigProperties.getTimeout(); |
|
// 配置获取(使用 configService)、配置封装、配置缓存等操作 |
|
nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService, |
|
timeout) |