Closed bnytezz closed 3 years ago
可以提供一下详细的日志吗?
可以提供一下详细的日志吗?
您好,我已经确定异常原因并解决,我查证发现是目前Nacos的bug,下面我会沾上我使用的版本以及service版本。
<!--Nacos Discovery-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<!--Nacos Config-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<!-- SpringCloud阿里巴巴 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
异常原因:因为我指定了 profiles: active: dev 而目前的nacos service版本为2.0.2,但是nacos会先请求${spring.application}.${file-extension},因为在我的配置中心不存在${spring.application}.${file-extension}配置,故而他无法完成装配,此时直接会抛出异常,DataSource数据源装配失败,也就是说其原因根本在于${spring.application}-${profiles.active}.${file-extension}使用该方式的情况下即使你的配置中心有了符合规定的配置,但是他依然不会读取,Nacos只读取${spring.application}.${file-extension}在配置中心中是否存在,并不会在乎${spring.application}-${profiles.active}.${file-extension}是否存在,即使存在也会抛出异常。
可以提供一下详细的日志吗?
这个BUG我本人认为非常严重!!!希望得到及时的解决。 @brotherlu-xcq
可以提供一下详细的日志吗?
如果需要复现请留下邮箱我会将BUG复现以截图方式发送给你
你直接贴到这个评论上,敏感信息打码就可以。社区里大家可以一起看看这个问题。
你直接贴到这个评论上,敏感信息打码就可以。社区里大家可以一起看看这个问题。
@brotherlu-xcq
上图中在
public
namespace中已经存在了hsy-partner-service-dev.yaml配置,当启动的时候可以发现如下报错
而当新增了hsy-partner-service.yaml并且依然指定profiles: active: dev继续重启
配置没有任何改变,但是启动成功了。可以知道Nacos在读默认的${spring.applicaion.name}.${file-extension}失败之后会直接抛出异常,并不会在乎${spring.application}-${profiles.active}.${file-extension}是否存在
删除${spring.application}-${profiles.active}.${file-extension}之后继续重启
重启成功。
这其实不是个Bug。注意看你Nacos控制台里创建的配置文件dataid
是没有带.yaml
后缀的,这是导致你描述的现象的直接原因。
看下面这段代码(com.alibaba.cloud.nacos.client.NacosPropertySourceLocator
),这里是Nacos客户端加载远程配置文件的逻辑。注意中文注释:
/**
* load configuration of application.
*/
private void loadApplicationConfiguration(
CompositePropertySource compositePropertySource, String dataIdPrefix,
NacosConfigProperties properties, Environment environment) {
String fileExtension = properties.getFileExtension();
String nacosGroup = properties.getGroup();
// load directly once by default
// 第一步加载:这里加载的dataid就是你配置的spring.application.name,默认其实是不带后缀的
loadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup,
fileExtension, true);
// load with suffix, which have a higher priority than the default
// 第二步加载:这里加载的dataid是spring.application.name.yaml,追加了文件后缀到dataid上
loadNacosDataIfPresent(compositePropertySource,
dataIdPrefix + DOT + fileExtension, nacosGroup, fileExtension, true);
// Loaded with profile, which have a higher priority than the suffix
// 第三步加载:最高优先级,加载带有profile的dataid,这里的dataid是spring.application.name-profile.yaml
for (String profile : environment.getActiveProfiles()) {
String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension;
loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup,
fileExtension, true);
}
}
也就是说,如果你Nacos配置文件里只有spring.application.name-profile
而没有spring.application.name-profile.yaml
,它是无法被加载的,而只能加载到spring.application.name
或spring.application.name.yaml
或spring.application.name-profile.yaml
,这三类文件。
是不是其实也可以考虑一下兼容这种情况,毕竟其他三种情况都尝试去加载了?
是不是其实也可以考虑一下兼容这种情况,毕竟其他三种情况都尝试去加载了?
@zarkzheng 我只是降低了日志打印等级,nacos日志中打印了带有-dev 带有文件后缀 以及不带文件后缀 他们的日志优先级顺序分别是 application.name > application.name.yaml > application.name-dev.yaml 具体顺序大概是这个,忘记了没有特意去记,总之这个顺序优先级是没错的,也就是说nacos在没有拿到application.name.yaml时也就无法完成DataSource装配,所以导致bug产生。我本人认为这就是bug,并且在低版本的时候这种方式是被兼容的,是可以正常使用的。
这其实不是个Bug。注意看你Nacos控制台里创建的配置文件
dataid
是没有带.yaml
后缀的,这是导致你描述的现象的直接原因。 看下面这段代码(com.alibaba.cloud.nacos.client.NacosPropertySourceLocator
),这里是Nacos客户端加载远程配置文件的逻辑。注意中文注释:/** * load configuration of application. */ private void loadApplicationConfiguration( CompositePropertySource compositePropertySource, String dataIdPrefix, NacosConfigProperties properties, Environment environment) { String fileExtension = properties.getFileExtension(); String nacosGroup = properties.getGroup(); // load directly once by default // 第一步加载:这里加载的dataid就是你配置的spring.application.name,默认其实是不带后缀的 loadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup, fileExtension, true); // load with suffix, which have a higher priority than the default // 第二步加载:这里加载的dataid是spring.application.name.yaml,追加了文件后缀到dataid上 loadNacosDataIfPresent(compositePropertySource, dataIdPrefix + DOT + fileExtension, nacosGroup, fileExtension, true); // Loaded with profile, which have a higher priority than the suffix // 第三步加载:最高优先级,加载带有profile的dataid,这里的dataid是spring.application.name-profile.yaml for (String profile : environment.getActiveProfiles()) { String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension; loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup, fileExtension, true); } }
也就是说,如果你Nacos配置文件里只有
spring.application.name-profile
而没有spring.application.name-profile.yaml
,它是无法被加载的,而只能加载到spring.application.name
或spring.application.name.yaml
或spring.application.name-profile.yaml
,这三类文件。
@zarkzheng 你可以看上边我传入的bug复现,你所说的{application.name}- profile.yaml他是存在的,因为配置的是yaml文件并且你把日志等级提升到debug之后你会发现nacos是全部都会请求,但是请求响应结果为null。
或者你可以试一下,在客户端使用spring-cloud-alibaba 2021.1版本的项目里,只在nacos server添加spring.application.name-profile.yaml
文件,注意dataid
带.yaml
后缀(你截图里的dataid
实际是spring.application.name-profile
而不是spring.application.name-profile.yaml
),然后启动一下,应该是可以正常启动的,无需spring.application.name.yaml
配置。
我看了一下老版本的实现,例如spring-cloud-alibaba 2.2.6.RELEASE,实现逻辑也是一样的。你之前用的哪个版本,可以加载spring.application.name-profile
不带.yaml
这种形式的配置?
你直接贴到这个评论上,敏感信息打码就可以。社区里大家可以一起看看这个问题。
部署到服务器又读不到了。。。
profile的文件控制是SCA来进行的,如果有疑问可以去SCA社区问一下,看下设计思路是什么样的。
我认为应该不是bug,是对使用的理解有问题。建议还是去看下SCA的wiki或者发个issue问一下,能帮助你解决和理解这个功能。如果最后的确不符合设计预期,那可能是SCA的bug。在SCA那边修复下即可。
dataId invalid,异常信息为dataID无效,但其实他是存在的,我已经确认了nameSpace和group和dataId