bootstrap.yml
配置文件在 SpringCloud
的项目中,我们常常会碰到另外一个配置文件 bootstrap.yml
。这个配置文件主要是用于应用程序上下文的引导阶段,该配置文件的加载是在 application.yml
之前。
bootstrap.yml
和application.yml
文件的区别可参考:What is the difference between putting a property on application.yml or bootstrap.yml in spring boot
在SpringCloud
中有两种上下文,一种是bootstrap
,另外一种是application
, bootstrap
是应用程序的父上下文。官方的原话是A Spring Cloud application operates by creating a “bootstrap” context, which is a parent context for the main application。
bootstrap.yml
配置文件的使用场景:
bootstrap
配置文件中添加连接到配置中心的信息,来加载外部配置中心的配置信息项目中 bootstrap.yml
示例
spring:
application:
name:
profiles:
active: local
cloud:
nacos:
# 远程配置
config:
server-addr:
namespace:
group: ${spring.profiles.active}
file-extension: yml
# 服务发现
discovery:
server-addr:
namespace:
group: ${spring.profiles.active}
在 SpringCloud
项目中,我们的配置常由配置中心进行统一管理,这就涉及到本地与远程配置文件的优先级问题。这里只说明遇到过的两种:SpringCloud Config
和Nacos
。
SpringCloud Config
SpringCloud Config
中的远程配置,默认是无法被本地覆盖,如果需要本地配置覆盖远程配置,需要在远程做如下配置:
spring:
cloud:
config:
allowOverride: true
overrideNone: true
overrideSystemProperties: false
上面的说法可以在如下链接中得到验证:https://cloud.spring.io/spring-cloud-commons/multi/multi__spring_cloud_context_application_context_services.html#overriding-bootstrap-properties
Nacos
Nacos
中的远程配置,似乎不支持本地覆盖,在Nacos
项目中Issue
中得到证实,似乎官方也没有这种打算。值得一提的是,即使通过命令行指定的参数,也不能覆盖远程配置。
开发过程中,希望服务(serviceA
)的某些节点的配置与其他节点配置不同,刚开始的想法是在启动命令行加入参数 spring.application.name=serviceB
,然后在配置中心 nacos
中复制一份serviceA
的配置命名为 service B
。但是实际测试中,不能修改application.name
的值,因为参与到一些业务配置。
接着我们想直接在命令行中加入区别于其他节点的参数,希望能够覆盖远程的配置,但前面也说过,命令行的配置无法覆盖远程Nacos
配置,且Nacos
没有提供支持覆盖的开关,所以也没能达到我们预期的结果。
实际测试的结果,配置优先级:nacos
上的配置 > 命令行配置 > system env
> classpath:application.yml
> classpath:bootstrap.yml
最后我们发现nacos
支持指定服务配置,以及服务发现的名称,这些配置是在 bootstap.yml
文件中指定,默认值是 spring.application.name
。实际测试结果,通过命令行可以覆盖该文件中的配置,这样正好能够满足我们的需求:不修改application.name
,又可以使部分节点的配置区别于其他节点。
java -jar ./app.jar --spring.profiles.active=local --spring.cloud.nacos.config.name=serviceB --spring.cloud.nacos.discovery.service=serviceB