相信朋友们在工作中都用到了多环境配置,在启动或打包时指定
spring.profiles.active
同时spring还提供了一个配置
spring.profiles.include
整个多环境配置的核心就是用到了这两个配置。
在应用时,spring.profiles.include的值一般是固定的,而spring.profiles.active是可变的,具体值一般由两种途径指定
1. 打包时,通过maven的profile配置获取
2. 启动时,通过参数指定, --spring.profiles.active=dev
spring:
profiles:
active: @spring.profiles.active@
# 比如下面配置了nacos,那么Spring会在所有jar的classes路径下查找application-nacos.yml, bootstrap-nacos.yml,找不到会忽略
include: all,web,business,seata,nacos
application:
name: @artifactId@
以前只知道application-nacos.yml, 并不知道原来bootstrap也可以这样。
SpringCloud有两种配置文件,bootstrap.yml的加载会比较早,方便配置nacos, 然后从nacos读取配置,而application.yml大家都比较熟悉了,用来配置具体项。
我们开始的方案是把nacos的addr和namespace放在maven的profile, 通过打包替换bootstrap.yml中的值,
spring:
profiles:
# @变量@,用来替换maven的properties的值
active: @spring.profiles.active@
include: all,web,business,seata,nacos
application:
name: @artifactId@
cloud:
nacos:
# 配置中心
config:
server-addr: @nacos.server.addr@
namespace: @nacos.namespace@
file-extension: yml
shared-configs[0]:
data-id: xxx-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
refresh: true
# 注册中心
discovery:
server-addr: @nacos.server.addr@
namespace: @nacos.namespace@
pom.xml的profiles
<profiles>
<!-- 按环境打包,配合bootstrap-nacos.yml -->
<profile>
<activation>
<!--默认激活-->
<activeByDefault>true</activeByDefault>
</activation>
<id>dev</id>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
<nacos.server.addr>xxxx</nacos.server.addr>
<nacos.namespace>xxxxx</nacos.namespace>
</properties>
</profile>
<profile>...</profile>
<profiles>
这好像也没什么问题,
但随着我们需求的变化,发版,有时候会同时发布多个环境,每个环境打一次包,太耗时;当然,我们是通过提前写好的shell脚本启动的,可以在启动时指定参数,
如下:
nacosadder='127.0.0.1:8848'
nacosnamespace='uuid'
springenv='dev'
startup=" --spring.profiles.active=${springenv} --spring.cloud.nacos.config.server-addr=${nacosadder} --spring.cloud.nacos.config.namespace=${nacosnamespace} --spring.cloud.nacos.discovery.namespace=${nacosnamespace} --spring.cloud.nacos.discovery.server-addr=${nacosadder} "
但这参数实在是太长了,有没有更好的方案呢? 一次灵感闪现,想到了bootstrap.yml是不是也可以像application-xx.yml这些写,然后实践尝试,果真可以,随后进行了改造。
由于nacos用到了注册和配置两个功能,启动时变量需要指定4个配置,曾经构想用${xx}引用的方式来避免nacos配置指定两次,然后Spring并不支持启动时指定变量a, 然后b又引用a,必须直接指定具体配置项。
下面上最终图
可能会有同学说,既然用到了nacos配置中心,那就把配置都放上去就行了,本地不用搞这么复杂的配置,
我的想法是这样的,优先以本地配置为主,就算没有nacos也可以正常运行,当需要实时修改配置时,再在nacos加上相关配置,用于覆盖本地配置。
毕竟大部分配置的修改频率不高,如果把配置都放在nacos,那每个环境都需要去加上配置,这对于开发人员还是很烦的,更严重的是容易忘记或遗漏。