- Spring Cloud Alibaba:Nacos Confi
- Spring Cloud Alibaba Nacos Confi
- Spring Cloud Alibaba Nacos Confi
- Spring Cloud Alibaba Nacos Confi
- Kitty中的动态线程池支持Nacos,Apollo多配置中心了
- Spring Cloud Alibaba 微服务商城系统
- 2022-08-02 Springcloud基础知识(20)-
- 2022-08-01 Springcloud基础知识(18)-
- 2022-08-02 Springcloud基础知识(19)-
- 2022-07-16 Springcloud基础知识(11)-
本文主要分析 Spring Cloud Alibaba Nacos 配置客户端读取配置的部分过程,逻辑入口是 com.alibaba.cloud.nacos.client.NacosPropertySourceLocator#locate
;通过本篇,
- 1、了解到 sharedConfigs、extensionConfigs 如何加载
- 2、应用配置加载时,dataId 的计算逻辑
- 3、如何通过 group 和 namespace 来隔离配置
- 4、如何禁用默认的 DEFAULT_GROUP
加载顺序和 sharedConfigs、extensionConfigs 加载逻辑
这里的配置主要指的是 sharedConfigs、extensionConfigs 以及用户通过 namespace+group+dataId 指定的应用配置。
加载顺序
// 配置临时存档的地方
CompositePropertySource composite = new CompositePropertySource(
NACOS_PROPERTY_SOURCE_NAME);
// 1、先加载 sharedConfigs
loadSharedConfiguration(composite);‘
// 2、接着加载 extensionConfigs
loadExtConfiguration(composite);
// 最后加载指定的应用配置
loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env);
这里除了需要关注顺序之后,还有一点非常重要,就是对于 sharedConfigs、extensionConfigs 两个指定的配置,他们不依赖用户指定的 group,而是使用默认的 DEFAULT_GROUP,下面来看。
sharedConfigs 加载逻辑
先通过代码大概理解下逻辑
private void loadSharedConfiguration(
CompositePropertySource compositePropertySource) {
// 通过配置获取 sharedConfigs 列表
List<NacosConfigProperties.Config> sharedConfigs = nacosConfigProperties
.getSharedConfigs();
// 如果没有配置,则啥都不做
if (!CollectionUtils.isEmpty(sharedConfigs)) {
checkConfiguration(sharedConfigs, "shared-configs");
loadNacosConfiguration(compositePropertySource, sharedConfigs);
}
}
假设我通过 sharedConfigs 指定的配置如下:
spring.cloud.nacos.config.shared-configs=
application.yaml,
application.properties,
application-staging.yaml,
application-staging.properties,
application-CN.properties,
application-staging_CN2.properties
通过 debug 面板看到,对于指定的 sharedConfigs,全部都挂在 DEFALUT_GROUP 下。

不管是 sharedConfigs 还是 extensionConfigs,抑或是用户指定 group 的配置,nacos 在读取配置时,都是优先从本地开始读,如果本地没有,才从远端配置服务端去读取。
spring.cloud.nacos.config.extension-config 配置加载和 sharedConfigs 基本一致,这里不展开介绍。
应用配置加载逻辑中的 dataId 计算
这里主要指的是加载用户指定的 group 情况下的应用配置加载,还是先通过代码看下基本逻辑:
private void loadApplicationConfiguration(
CompositePropertySource compositePropertySource, String dataIdPrefix,
NacosConfigProperties properties, Environment environment) {
// 先获取文件的后缀名,比如 yml ,properties
String fileExtension = properties.getFileExtension();
// 获取 group
String nacosGroup = properties.getGroup();
// load directly once by default
loadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup,
fileExtension, true);
// load with suffix, which have a higher priority than the default
loadNacosDataIfPresent(compositePropertySource,
dataIdPrefix + DOT + fileExtension, nacosGroup, fileExtension, true);
// Loaded with profile, which have a higher priority than the suffix
for (String profile : environment.getActiveProfiles()) {
String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension;
loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup,
fileExtension, true);
}
}
上面代码片段中,加载配置有三种,第一是直接加载,这里的 dataId 使用的是 dataIdPrefix;第二是通过指定后缀加载;最后是通过 指定的 profile 加载。假设 spring.application.name 为 login-service,fileExtension 是 yaml, profile 为 staging,test,下面看下 dataId 的计算。
直接加载
第一部分是加载默认的,这里的默认指的是 dataId 为 dataIdPrefix,dataIdPrefix 可以通过 spring.cloud.nacos.config.prefix 配置,如果没有配置,则使用的是 spring.application.name;这里去加载时,会有从本地文件先加载的逻辑,以这种情况为例,Mac 下本地路径为:
/Users/xxx/nacos/config/xxx/data/config-data-tenant/{namespace}/{group}/{dataId}
如果本地没有,那就根据 namespace, group 和 dataId 去 nacos 服务端去获取,在直接加载这部分。
使用指定的 suffix 加载
ns 和 group 都没变,但是 dataId 变成了 dataIdPrefix + DOT + fileExtension
,所以 dataId 就变成了 login-service.yaml,其他加载逻辑和第一部分保持一致。
使用指定的 profile
从代码可以看到,如果指定了多个 profile,则会遍历所有 profile 然后拼接 dataId;这里 dataId 的计算逻辑是 dataIdPrefix + SEP1 + profile + DOT + fileExtension
;比如 dataIdPrefix 是 login-service,profile 是 staging,fileExtension 是 yaml,那么得到的 dataId 就是 login-service-staging.yaml,然后在根据 ns、group 和这个计算出来的 dataId 去 nacos 服务端拉去配置,其他逻辑和前面加载配置逻辑一致。
配置加载过程
1、优先使用本地配,代码逻辑在
com.alibaba.nacos.client.config.NacosConfigService#getConfigInner
// 优先使用本地配置
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);

2、配置资源定位
配置资源定位通过三个参数 namespace + group + dataId 来确定

从远端拉去之后,会优先创建本地快照,便于下次加载时能够优先从本地加载到
3、文件格式解析 上一步拿到的data,原始数据是字符串类型,然后会根据配置的后缀名,来匹配一个 loader 解析器,nacos 中提供了 4 种类型的解析器

通过解析器将 string 类型的数据进行处理,然后放到 propertySource,这些 propertySource 会被放在 NACOS_PROPERTY_SOURCE_REPOSITORY 这个 ma p 结构中,ke y 为 dataId,group

小结
nacos 配置最高级别的隔离是 namespace,其后是 group;如果有配置隔离的诉求,建议优先使用 namespace 进行隔离。因为对于 sharedConfigs 和 extensionConfigs 来说,他们使用的是默认的 DEFALUT_GROUP,所以如果你配置了 sharedConfigs 和 extensionConfigs ,期望通过指定 group 进行隔离是做不到的。
作者:磊叔的技术博客
链接:https://juejin.cn/post/7074569286525648910
网友评论