1. 程式人生 > >Spring boot 的profile功能如何實現多環境配置自動切換

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

通常服務端應用開發需要經過以下幾個流程:

開發 -> 測試 -> 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容器技術,所以非常有意義。

——————————————————分割線——————————————————

我是黑少,直男一枚,微服務硬核玩家,喜歡分享、愛交友人、崇尚“實踐出真知”的理念,以折騰鼓搗程式碼為樂

我的微信:heishao (備註:開源中國 )

微信公號:黑少微服務,專注微服務技術分享,非技術不八卦!