V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
heishao
V2EX  ›  推广

Spring boot 的 profile 功能如何实现多环境配置自动切换

  •  
  •   heishao · 2018-11-06 11:10:53 +08:00 · 1597 次点击
    这是一个创建于 1990 天前的主题,其中的信息可能已经有所发展或是发生改变。

    通常服务端应用开发需要经过以下几个流程:

    开发 -> 测试 -> RC 验证 -> 上线

    这就涉及到四个不同的环境,开发环境、测试环境、RC 环境以及生产环境,为了避免不同环境之间相互干扰,通常需要独立部署数据库、缓存服务器等,那么应用配置也要做相应的调整。

    为了解决不同环境配置切换问题,很多人的做法是:把配置文件根据不同的环境,放到不同的目录或文件中,打包时通过 gradle 或 maven,通过命令行参数指定要打哪个环境的包。这样就可以针对不同的环境生成不同的包。但这样的做法有以下几个问题:

    • gradle 或 maven 打包脚本文件需要重复编写“选择文件”打包的逻辑,增加很多重复劳动的成功;
    • 在 jenkins 等集成环境中,需要针对每个应用,不同的环境做相应的设置;
    • 需要管理不同环境的包,带来的成本;部署时,需要注意包与运行环境是否一致;
    • 如果运行在 docker 中时,因为包不同所以要针对不同的环境,构建相应的镜像。 这时也许有人会说,把配置都从包里剥离出来,放到配置中心就可以了,但是不同环境对应的配置中心地址也是不一样的。

    Spring 中的 Profile 是什么?

    Spring 中的 Profile 功能其实早在 Spring 3.1 的版本就已经出来,它可以理解为我们在 Spring 容器中所定义的 Bean 的逻辑组名称,只有当这些 Profile 被激活的时候,才会将 Profile 中所对应的 Bean 注册到 Spring 容器中。

    举个更具体的例子,我们以前所定义的 Bean,当 Spring 容器一启动的时候,就会一股脑的全部加载这些信息完成对 Bean 的创建;而使用了 Profile 之后,它会将 Bean 的定义进行更细粒度的划分,将这些定义的 Bean 划分为几个不同的组,当 Spring 容器加载配置信息的时候,首先查找激活的 Profile,然后只会去加载被激活的组中所定义的 Bean 信息,而不被激活的 Profile 中所定义的 Bean 定义信息是不会加载用于创建 Bean 的。

    为了使用不同的环境,我们首先对不同的环境,定义相应的 profile 名称。

    比如,开发环境的 profile 为:dev ;测试环境的 profile 为:test ; RC 环境的 profile 为:rc ;生产环境的 profile 为:prod。

    下面举个 dubbo 不同环境下,使用不同配置的方法:

    上面例子中,当激活相应的 profile 时,相应的配置文件才会导入。

    比如:profile 为 dev 时,导入 dubbo-dev.properties。

    注意:所有 spring xml schema 的版本必须是 4.0 以上,比如: http://www.springframework.org/schema/util/spring-util-4.3.xsd 。spring 默认 profile 为 default, 在没有指定 profile 的,会被默认为 default。

    如果我们使用配置中心的话,上面的配置还可以更简单。等配置中心投产后我们再讨论。

    Spring boot 中使用 profile 切换配置

    Spring boot 中默认加载的配置文件是:application.properties 或 application.yml 。当激活 profile 后(后面我们讨论如何激活 profile ),可以通过 profile 自动选择加载的 application-{profile}.properties 或 application-{profile}.yml 格式的配置文件。

    比如:profile 为 dev 时,会加载 application.properties 或 application.yml 外,还会加载 application-dev.properties 或 application-dev.yml 配置。

    另外如果引入 Spring cloud 时,也会加载启动配置 bootstrap.properties 或 bootstrap.yml 以及 bootstrap-{profile}.properties 或 bootstrap-{profile}.yml 。

    所以把各个环境公共的配置写在 application.properties 或 application.yml 中。把不同环境的配置写在 application-{profile}.properties 或 application-{profile}.yml 中。

    @Profile 注解的使用

    使用 java 进行配置时,可以通过 @Profile 注解,实现不同环境使用配置策略。比如 swagger 现在使用很普遍了,但是它存在一定的安全问题,如果生产环境中也暴露 swagger 的话,风险还是比较大的,建议只在开发环境和测试环境启用,配置例子如下:

    将上面的代码保存到 logback-spring.xml 文件中,而不是 logback.xml 中。

    logback 中 profile 的使用

    在开发环境或测试环境中,为了方便排查问题,我们会使用 DEBUG 甚至 TRACE 级别的日志,而在生产环境中,避免日志增长过快,尽量只是输出 ERROR 级别的日志。这就需要日志配置也要能根据不同的环境,使用不同的配置策略。

    spring boot 中的 logback 就可以满足这样的需求,例子如下:

    将上面的代码保存到 logback-spring.xml 文件中,而不是 logback.xml 中。

    Spring boot 激活 profile 的几种方式

    在配置文件中直接指定 spring.profiles.active=test 这种方式非常不灵活,在实际开发部不太会使用到

    使用占位符 在打包时替换,以 mavne 为例: 首先在配置文件中增加: [email protected]@ 在 pom.xml 中增加不同环境打包的配置: 执行打包命令: mvn package -Ptest
    缺点:每次打包都要指定 profile

    JVM 参数方式

    java 命令行指定: java -jar app.jar --spring.profiles.active=dev tomcat 中 catalina.bat (.sh 中不用“ set ”) 添加 JAVA_OPS。通过设置 active 选择不同配置文件: set JAVA_OPTS="-Dspring.profiles.active=test" eclipse 中启动 tomcat。项目右键 run as –> run configuration –>Arguments –> VM arguments 中添加。 -Dspring.profiles.active="dev" 在微服务的时代,会不会觉得有点麻烦呢?

    web.xml 方式

    <init-param> <param-name>spring.profiles.active</param-name> <param-value>prod</param-value> </init-param>

    标注方式( junit 单元测试非常实用) @ActiveProfiles({"dev"})

    ENV 方式(建议使用此方式)

    设置系统环境变量:SPRING_PROFILES_ACTIVE (注意:是大写) 比如 mac 开发环境中设置环境变量的方法: vi ~/.bash_profile 在~/.bash_profile 中增加如下内容: export SPRING_PROFILES_ACTIVE=dev

    注意: mac eclipse 中是获取不到环境变量的解决办法,参考这文章进行处理,http://blog.csdn.net/zhzdeng/article/details/64921967

    总结

    上面关于 profile 的东西,基本能满足工作的需要了。使用 profile 后,可以减化因不同环境配置差异,而带来的配置管理以及打包工作。

    尽量使用环境变量来激活 profile,如果是可执行的包,也可以使用 java 命令行指定,其它方式不建议使用。

    使用 profile 后,使得应用能更容易接入配置中心,以及使用 docker 容器技术,所以非常有意义。

    ———————————————————————分割线—————————————————————————

    我是小微,专注微服务技术分享,致力挖掘更多“高、精、全”的微服务知识分享给大家。

    我的微信:weiweiweiblack (备注:v2ex )

    微信公号:黑少微服务,“分享技术,热爱生活”,欢迎关注

    xiaoxinshiwo
        1
    xiaoxinshiwo  
       2018-11-06 12:03:04 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5349 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 47ms · UTC 01:32 · PVG 09:32 · LAX 18:32 · JFK 21:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.