Spring boot 的profile功能如何實現多環境配置自動切換

一般服務端應用開發須要通過如下幾個流程:java

開發 -> 測試 -> RC驗證 -> 上線web

這就涉及到四個不一樣的環境,開發環境、測試環境、RC環境以及生產環境,爲了不不一樣環境之間相互干擾,一般須要獨立部署數據庫、緩存服務器等,那麼應用配置也要作相應的調整。spring

爲了解決不一樣環境配置切換問題,不少人的作法是:把配置文件根據不一樣的環境,放到不一樣的目錄或文件中,打包時經過gradle或maven,經過命令行參數指定要打哪一個環境的包。這樣就能夠針對不一樣的環境生成不一樣的包。但這樣的作法有如下幾個問題:docker

  • 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的。bootstrap

爲了使用不一樣的環境,咱們首先對不一樣的環境,定義相應的profile名稱。緩存

好比,開發環境的profile爲:dev;測試環境的profile爲:test;RC環境的profile爲:rc;生產環境的profile爲:prod。tomcat

下面舉個dubbo不一樣環境下,使用不一樣配置的方法:
安全

上面例子中,當激活相應的profile時,相應的配置文件纔會導入。bash

好比: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爲例:
首先在配置文件中增長:
spring.profiles.active=@package.target@
在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方式


spring.profiles.active
prod

標註方式(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容器技術,因此很是有意義。

相關文章
相關標籤/搜索