SpringBoot学习之旅(十一)---运行时环境、配置文件自动切换

需求说明

开发过程中,经常出现的环境必定会有以下几个:开发环境、测试环境、预发布环境(可能会有,可能没有)、正式环境;由于这些环境的存在,我们就不得不去维护这一系列环境的配置(如数据库连接、商户资料等等)及版本,那么要如何去管理这些配置呢?

常用的方式

  • 第一种:版本管理工具
    比如,通过git去维护不同的分支,不同的分支有不同的配置文件信息;发布的时候,切换不同的分布打不同版本的包进行上传发布
    • 缺点
      • 分支众多且复杂;因为不同的版本存在不同的分支,因此在分支的维护耗时大大增加
      • 配置文件混乱;因为使用的是同一个配置文件,只不过是通过不同的分支,维护着同一个配置文件中的不同配置项
  • 第二种:通过SpringBoot的配置不同环境的配置文件,运行时进行切换
    通过配置多个环境的配置文件,运行时通过环境(spring.profiles.active)切换,实现不通配置文件的切换,
    推荐使用该做法,同时以下将详细介绍该方法的实现方式及使用方式;能大大提高代码的维护性及版本的可控制性
    • 缺点
      • 容易遗漏;由于不同的环境是使用的不同的配置,因此,可能出现开发环境做了修改,但是测试环境、正式环境忘记调整了,从而导致本地运行正常,发布之后不正常的问题;这个算问题也不算问题,思维清晰缜密是一个程序员的基本素养。
  • 第三种:通过SpringBoot Config进行配置文件管理
    其实他和第二种的差别不算大,也都是通过当前运行的不同环境(spring.profiles.active),进行配置文件的切换,只不过是这些配置文件都是通过git进行管理维护,可以实现一些权限的控制,自动刷新配置等高级操作;
    • 缺点
      • 使用的复杂度相对较高;可以参考SpringBoot学习之旅(九)---超详细的自动刷新配置教程;
      • 单独的SpringBoot无法使用;至少得配合Eureka和git来使用。

源码

下载地址

项目级配置

  • 配置文件说明
    SpringBoot项目通常都是通过application.yml进行当前项目的配置,如数据库、redis、mq、编码等等的配置项;那么当环境变化的时候,如何去更换不通的配置参数呢?如:不同环境的数据库配置;那么我们就将配置文件分为一下四个(注意: 这里文件名必须使用application开头):
    • application.yml ;用于配置公共的配置项,即各个环境都需要,且配置都相同的项;
        server:
          port: 8080 #设置项目的端口
        spring:
          profiles:
            active: local #设置项目运行的环境
  • application-local.yml ;用于配置本地环境的配置项
        conf: 本地
  • application-dev.yml ;用于配置测试环境的配置项
        conf: 测试
  • application-pro.yml ;用于配置正式环境的配置项
        conf: 正式
  • 编写一个接口用于测试当前运行的环境下conf的值
        @RestController
        public class ConfController {
                @Value("${conf}")
                public String conf;
    
                @GetMapping("conf")
                public String getConf() {
                        return conf;
                }
        }

  • 运行时环境自定
    #java -jar jar文件地址 --spring.profiles.active=环境别名
    java -jar target/myconfig.jar --spring.profiles.active=pro

  • 测试效果
    • 切换测试环境
      SpringBoot学习之旅(十一)---运行时环境、配置文件自动切换_第1张图片
      SpringBoot学习之旅(十一)---运行时环境、配置文件自动切换_第2张图片
    • 切换正式环境
      SpringBoot学习之旅(十一)---运行时环境、配置文件自动切换_第3张图片
      SpringBoot学习之旅(十一)---运行时环境、配置文件自动切换_第4张图片
    这样同一个版本包即可实现各个环境的切换

自定义配置

业务开发过程中,除了项目的一些基础配置之外,不可避免的会存在一些自定义的业务流程配置;同样也就不可避免的会存在不同环境下的配置文件,以下即演示自定义配置文件的动态切换;

  • 配置文件说明
    • yml-config.yml;公共配置,所有环境都存在且值相同的配置文件
        busi:
            key: va-all
  • yml-config-local.yml;本地开发环境配置文件
        busi:
            key1: va1-local
            key2: va2-local
            key3:
                keyc1: vac1-local
            key4:
                okey1: ova1-local
                okey2: ova2-local
            key5: 9,10
  • yml-config-dev.yml;测试环境配置文件
        busi:
            key1: va1-dev
            key2: va2-dev
            key3:
                keyc1: vac1-dev
            key4:
                okey1: ova1-dev
                okey2: ova2-dev
            key5: 6,7,8
  • yml-config-pro.yml;正式环境配置文件
        busi:
            key1: va1-pro
            key2: va2-pro
            key3:
                keyc1: vac1-pro
            key4:
                okey1: ova1-pro
                okey2: ova2-pro
            key5: 1,2,3,4,5

SpringBoot学习之旅(十一)---运行时环境、配置文件自动切换_第5张图片

  • 配置自动将配置文件注入为对象
    由于上面使用的是yml格式,因此准备一个用于加载yml格式的工厂对象
        public class YamlPropertyLoaderFactory extends DefaultPropertySourceFactory {
                @Override
                public PropertySource createPropertySource(String name, EncodedResource resource) throws IOException {
                        if (resource == null) {
                                return super.createPropertySource(name, resource);
                        }
    
                        return new YamlPropertySourceLoader().load(resource.getResource().getFilename(), resource.getResource()).get(0);
                }
        }

添加业务配置对象

        @Data
        @Component
        //当前要注入的所有属性的前缀
        @ConfigurationProperties(prefix = "busi")
        //指定要扫描的文件路径,${spring.profiles.active}用于指定当前运行环境的配置文件
        //YamlPropertyLoaderFactory yaml文件加载工厂,默认是使用的propertes加载工厂,如果配置文件后缀是propertes,那么就不用配置factory属性
        @PropertySource(value = {"classpath:myconfig/yml-config.yml","classpath:myconfig/yml-config-${spring.profiles.active}.yml"}, encoding = "UTF-8", factory = YamlPropertyLoaderFactory.class)
        public class BusiConfig {
                private String key;
    
                private String key1;
    
                private String key2;
    
                //以map的形式接受多个子属性
                private Map key3;
    
                //以对象接口多个子属性
                private OtherConfig key4;
    
                //以列表的形式
                private List key5;
        }

OtherConfig 对象

        @Data
        public class OtherConfig {
                private String okey1;
                private String okey2;
        }
  • 准备一个用于测试的接口
        @RestController
        public class BusiController {
                @Autowired
                BusiConfig busiConfig;
    
                @GetMapping("busiconf")
                public BusiConfig busiConfig(){
                        return busiConfig;
                }
        }


  • 效果测试
    • 切换测试环境
      SpringBoot学习之旅(十一)---运行时环境、配置文件自动切换_第6张图片
    • 切换正式环境
      SpringBoot学习之旅(十一)---运行时环境、配置文件自动切换_第7张图片

Docker方式运行

既然是使用的同一个包在运行时通过环境变量进行切换,那么如果使用docker的方式运行的时候,要如何配置来实现一个镜像在运行时进行环境切换呢?

  • 编写DockerFile
    FROM hub.c.163.com/library/java:8-alpine

    #指明该镜像的作者
    MAINTAINER lupf XXX

    #添加文件
    ADD target/*.jar myconfig.jar

    #改镜像监听的端口
    EXPOSE 8080

    #指定镜像可以像一个可执行文件一样执行
    ENTRYPOINT ["java","-jar","-Duser.timezone=GMT 8","/myconfig.jar"]
  • 构建镜像
    //构建一个镜像名为: myconfig  版本为:1.0.0的镜像
    docker build -t myconfig:1.0.0 .
  • 运行镜像
    #docker run -p 端口映射 --name=容器别名 镜像名:版本  --spring.profiles.active=运行环境
    docker run -p 8080:8080 --name=myconfig myconfig:1.0.0 --spring.profiles.active=dev

运行容器时通过指定(spring.profiles.active)进行运行时环境切换

    
到此! 运行时配置文件自动切换即可完成!

你可能感兴趣的:(后端)