相信朋友们在工作中都用到了多环境配置,在启动或打包时指定

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,那每个环境都需要去加上配置,这对于开发人员还是很烦的,更严重的是容易忘记或遗漏。

 

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐