记录NACOS遇到的问题
自定义扩展的 Data Id 配置不能正确解析yaml文件
如下图所示
本地配置文件如下:
spring:
application:
name: mall-config #微服务名称
profiles:
active: yzw
cloud:
nacos:
server-addr: 192.168.0.108:8848/nacos
discovery:
namespace: d10ab342-519b-43c1-9617-a554b5c55f3b
group: yzw
config:
namespace: d10ab342-519b-43c1-9617-a554b5c55f3b
group: config
#默认配置文件为properties
#一旦修改修改了非properties文件的配置文件, 就必须通过file-extension进行设置, 只针对默认的和profiles.active
file-extension: yaml
refresh-enabled: true # 默认true 如果为false 则不会监听 配置中心的变化
shared-configs: # 自定义data-id
- data-id: mall-config1
- data-id: mall-config2
refresh: true # 默认为false ,如果为true Data Id 既不在默认的组,也支持动态刷新, 其他都不能刷新
group: config
extension-configs:
- data-id: mall-config3
refresh: true
group: config
# profiles>默认的application.name获取的配置文件>extension-configs>shared-configs
@Value(“${refresh.scope}”)
启动报错, 报错信息如下
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.orderController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'refresh.scope' in value "${refresh.scope}"
只能将nacos服务器上配置改为 如下图所示, 才可获取成功
ps:使用默认配置以及profiles模式配置都没问题, 使用extension-configs和extension-configs均不能正确解析yaml
ps: 等待解决
如下所示:获取不到shared.common.property1, 可能获取到shared.common.property3的值为123
========================================
问题已解决
问题追踪
项目run()执行后会解析加载配置文件,会调用NacosPropertySourceLocator.locate(Environment env)方法,【监听配置中心的监听器的监听事件也会调用此方法】如下:
public PropertySource<?> locate(Environment env) {
this.nacosConfigProperties.setEnvironment(env);
ConfigService configService = this.nacosConfigManager.getConfigService();
if (null == configService) {
log.warn("no instance of config service found, can't load config from nacos");
return null;
} else {
long timeout = (long)this.nacosConfigProperties.getTimeout();
this.nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService, timeout);
String name = this.nacosConfigProperties.getName();
String dataIdPrefix = this.nacosConfigProperties.getPrefix();
if (StringUtils.isEmpty(dataIdPrefix)) {
dataIdPrefix = name;
}
if (StringUtils.isEmpty(dataIdPrefix)) {
dataIdPrefix = env.getProperty("spring.application.name");
}
CompositePropertySource composite = new CompositePropertySource("NACOS");
this.loadSharedConfiguration(composite);
this.loadExtConfiguration(composite);
this.loadApplicationConfiguration(composite, dataIdPrefix, this.nacosConfigProperties, env);
return composite;
}
}
loadSharedConfiguration和loadExtConfiguration方法, 里面会执行loadNacosConfiguration方法解析加载配置文件
private void loadNacosConfiguration(final CompositePropertySource composite, List<Config> configs) {
Config config;
String fileExtension;
for(Iterator var3 = configs.iterator(); var3.hasNext(); this.loadNacosDataIfPresent(composite, config.getDataId(), config.getGroup(), fileExtension, config.isRefresh())) {
config = (Config)var3.next();
fileExtension = config.getFileExtension();
if (StringUtils.isEmpty(fileExtension)) {
fileExtension = NacosDataParserHandler.getInstance().getFileExtension(config.getDataId());
}
}
}
注意, fileExtension = config.getFileExtension();文件的类型是config对象的fileExtension属性, fileExtension为空或null时,会默认为properties类型。【而config是nacos加载NacosConfigManager时解析bootstrap文件生成的, todo:未追踪到对应加载逻辑, 只是得知上述一系列步骤都是在创建nacosPropertySourceLocator的Bean对象的过程中的】
public static class Config {
private String dataId;
private String group;
private String fileExtension;
private boolean refresh;
}
所以当我们自定义配置data id的时候一定要加上文件类型