Spring Boot2.x教程:(六)一次线上剔除nacos服务的经历——bootstrap.yml与application.yml的区别


大家好,我是欧阳方超,可以扫描下方二维码关注我的公众号“欧阳方超”,后续内容将在公众号首发。
在这里插入图片描述

在这里插入图片描述

1、概述

项目中使用了nacos,但是第三方检测时扫描出一些问题(没看到具体是什么问题),修复这些问题吧还挺费劲,索性就不用nacos了吧,把配置信息全部写到yml中,随工程一起打包到jar中。

项目中使用的spring boot、spring cloud、spring cloud alibaba版本信息如下:

项目版本
spring-boot2.3.7.RELEASE
spring-cloudHoxton.SR12
spring-cloud-alibaba2.2.6.RELEASE
原本我以为只要把nacos中的配置信息写到工程代码中,就可以了呢,但是一直不行,期间遇到两个问题,一个是项目启动后一直去连本地的nacos服务,另一个是yml中的自定义配置一直找不到。

2、问题解决

2.1、问题一——连接本地的nacos服务

本不想连接nacos了,配置文件中连接nacos的信息也去掉了,为什么启动时还在疯狂连接本地的nacos呢,报错信息如下:

2024-10-09 16:01:12.776 ERROR 32000 --- [           main] c.a.n.c.config.http.ServerHttpAgent      : [NACOS SocketTimeoutException httpGet] currentServerAddr:http://localhost:8848, err : connect timed out
2024-10-09 16:01:13.786 ERROR 32000 --- [           main] c.a.n.c.config.http.ServerHttpAgent      : [NACOS SocketTimeoutException httpGet] currentServerAddr:http://localhost:8848, err : connect timed out
2024-10-09 16:01:14.796 ERROR 32000 --- [           main] c.a.n.c.config.http.ServerHttpAgent      : [NACOS SocketTimeoutException httpGet] currentServerAddr:http://localhost:8848, err : connect timed out
2024-10-09 16:01:14.796 ERROR 32000 --- [           main] c.a.n.c.config.http.ServerHttpAgent      : no available server
2024-10-09 16:01:14.802 ERROR 32000 --- [           main] c.a.n.client.config.impl.ClientWorker    : [fixed-localhost_8848] [sub-server] get server config exception, dataId=service, group=DEFAULT_GROUP, tenant=

java.net.ConnectException: no available server
	at com.alibaba.nacos.client.config.http.ServerHttpAgent.httpGet(ServerHttpAgent.java:134) ~[nacos-client-1.4.1.jar:na]
	at com.alibaba.nacos.client.config.http.MetricsHttpAgent.httpGet(MetricsHttpAgent.java:51) ~[nacos-client-1.4.1.jar:na]
	at com.alibaba.nacos.client.config.impl.ClientWorker.getServerConfig(ClientWorker.java:274) ~[nacos-client-1.4.1.jar:na]

原来啊,当在项目中引入 spring-cloud-starter-alibaba-nacos-config、spring-cloud-starter-alibaba-nacos-discovery依赖时,Spring Cloud Alibaba 会自动配置 Nacos 客户端。默认情况下,它会尝试连接到本地运行的 Nacos 实例(通常是在 localhost:8848),除非在配置文件中明确指定其他地址,所以把下面的依赖去掉,即可解决项目持续去连本地nacos服务的问题。

<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

<dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

2.2、问题二——自定义配置找不到

连接本地nacos的问题解决掉之后,又遇到了新的问题,项目中使用了很多@Value注解来读取配置文件中的配置信息,但是一直就是读不到,报Could not resolve placeholder ‘xxx.xxx’ in value “${xxx.xxx}”这样的错误,原来啊,在之前使用nacos时配置文件用的是bootstrap.yml,这个问题有两个解决办法,其一是把bootstrap.yml改为application.yml,其二是添加spring-cloud-starter-bootstrap依赖。

2.2.1、bootstrap.yml改为application.yml

把bootstrap.yml改为application.yml之所以可行,是因为他俩之间存在着一些区别。
加载顺序:
bootstrap.yml:在 Spring Boot 启动时,首先加载该文件。它主要用于配置与应用程序上下文有关的设置,例如服务发现、配置服务器等。由于其优先级较高,任何在此文件中定义的属性都会在后续加载的配置文件中被覆盖。
application.yml:在 bootstrap.yml 加载之后加载。它用于定义应用程序特定的配置,如数据库连接、日志级别等。
用途:
bootstrap.yml:通常用于设置外部配置源(如 Spring Cloud Config 服务器)和其他与应用程序启动相关的配置。
application.yml:用于存储应用程序的具体配置,当不需要使用 Spring Cloud Config Server或nacos时使用。
同时使用两类配置文件
当然也会存在同时使用bootstrap.yml和application.yml的情况,在使用 Spring Cloud Config Server或nacos的场景下,通常会同时使用 bootstrap.yml 来配置客户端与 Config Server 的连接,以及 application.yml 来存放本地的默认配置或那些不希望通过 Config Server 管理的配置项。
此外,即使不使用Spring Cloud Config Server或nacos,也可以在bootstrap.yml中指定active那个配置文件,然后存放具体配置信息的文件以application-xxx.yml的方式进行命名。

2.2.2、添加spring-cloud-starter-bootstrap

spring-cloud-starter-bootstrap 是 Spring Cloud 项目中的一个重要 Starter 依赖,它的主要作用是支持 Bootstrap 配置文件的加载和管理。Bootstrap 配置文件的引入是为了更好地管理应用程序的启动配置,特别是在涉及外部配置源时(如 Spring Cloud Config Server)。
不过从 Spring Boot 2.4.x 开始,Bootstrap 配置文件(bootstrap.properties 或 bootstrap.yml)的支持需要显式引入 spring-cloud-starter-bootstrap 依赖。这一变化旨在简化配置管理,同时保持灵活性。
小插曲
我在引入spring-cloud-starter-bootstrap时遇到这样一个问题,我的项目是基于maven的多模块项目,在根pom中已经写了如下的依赖管理:

<dependencyManagement>
        <dependencies>
            <!-- 引入Spring Cloud依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
       </dependencies>
</dependencyManagement>

理论上我只要在相应的在子module的pom中,添加以下依赖即可(不需要版本号):

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

但是实际更新依赖时报错了,提示spring-cloud-starter-bootstrap这个依赖缺少version,这是因为spring-cloud-starter-bootstrap是从Spring Cloud 2020.0.x才开始引入的,所以切换一下Spring Cloud版本即可,当然Spring Cloud Alibaba和Spring Boot版本也需要调整,最终我把版本调整为了如下状态:

项目版本
spring-boot2.4.9
spring-cloud2020.0.5
spring-cloud-alibaba2020.0.RC1
调整后,在子module中引入spring-cloud-starter-bootstrap依赖时便不再需要版本信息。

3、总结

一次去除线上nacos服务引发的问题,这也充分暴漏了对bootstrap.yml和application.yml的了解不足,同时也没有跟上Spring Cloud变迁时本应留意的一些问题,以后需要定期阅读 Spring Cloud 和 Spring Boot 的官方文档,了解最新版本的变化和最佳实践,以便更好地应对项目中的配置管理。
我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。我们下次见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值