引言
最近在学习 Spring Cloud Alibaba,用到了 Nacos 配置中心。Nacos 是 Spring Cloud Alibaba 中的一个组件,通常用作服务注册中心以及配置中心。
问题复现
项目中有一个如图所示的消息模块:
在 application.yml 中做了如下配置:
spring:
application:
name: message
cloud:
nacos:
config:
server-addr: localhost:8848
file-extension: yaml
group: DEFAULT_GROUP
主要配置了服务的名称、Nacos 注册中心的地址、配置文件的后缀名以及组的名称,我在 Nacos 注册中心上做了如下配置:
Nacos 默认会在启动的时候去配置中心上读取名为 ${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
的配置文件,但是在启动的时候报了如下的错误:
意思是 Spring Boot 项目启动失败,url 属性未指定,DataSource 创建失败。
这里有一个小插曲:在高版本的 Spring Boot 中,默认是要创建 DataSource 的,否则无法启动,我们可以在 Spring Boot 的主启动类的 @SpringBootApplication 上加一个参数,排除掉 DataSourceAutoConfiguration,如下所示:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
但是,在这个服务中,我们是需要配置数据源,并且已经配置了数据源的,为什么会启动失败呢?
问题排查
关于排查问题,我们首先要做的就是看日志,先看控制台输出:
我们发现程序首先会去配置中心上加载名为 message 和 message.properties 的配置文件,读到这里大家会不会有点奇怪,我们配置的后缀名明明是 yaml,为什么会去读 message.properties 呢?带着这个疑问,请继续往下读。
如果让我去设计一个注册中心的话,在程序启动的时候,我会首先解析出配置文件,找到注册中心的地址,恰恰 Nacos 也是这样做的。如果你有一定的源码阅读功底的话,你应该会很快的找到 Nacos 里面的 NacosPropertySourceBuilder 类,里面有个 build 方法。没错,这个类就是用来解析配置文件,构造 NacosPropertySource 对象的,我们在这个方法的第一行上打上断点,以 Debug 模式运行,发现这个断点一共运行了两次,两次的对象的值如下:
我们发现,这与日志里的值一样,并且并没有解析我们的配置文件,采用的是默认的配置,为什么会这样呢?
问题解决
我们把配置文件名改为 bootstrap.yml,再次运行。
我们可以看到项目正常启动了!
总结
这是一个非常细节的问题,我原先以为我们把 Nacos 的配置信息写在默认的 application.yml 文件中就可以加载,但是事实并非如此,Nacos 的配置信息必须写在 bootstrap.properties 或者 bootstrap.yml 文件中,以后要多加注意!