iT邦幫忙

2021 iThome 鐵人賽

DAY 27
1
Software Development

Wow ! There is no doubt about Learn Spring framework in a month.系列 第 27

[Day - 27] - Spring 環境管理思想與設計

Abstract

許多開發者勢必會遇到一種狀況,就是在上線前勢必會先放到測試主機進行測試,我們稱之開發環境(Develop Environment,但每次都要修改組態檔(Config file)內部的DB連線資訊、配置檔內容,今天小編就依照Spring所預設的區分測試環境的設定檔,依照不同的環境可透過命令參數進行切換,這樣開發者就可依照不同環境自動觸發不同的組態檔,今日小編所提供的範例切分三種環境,區分為DEV、UAT及PROD環境,小編僅提供設定方法進行介紹,主要為了讓各位開發者離CI/CD會越離越近,現在就開始準備切割你的環境囉!

Principle Introduction

在每個專案都會預設一個application.properties或application.yml,故小編僅針對application.properties進行設計,此時專案的預設profile key為default,故Spring提供一項配置命令spring.profiles.active進行設置環境配置檔索引名稱,其相關聯的配置檔須遵循命名原則,故原生在通過部署的時候,可以通過指令java -jar XXX.jar --spring.profiles.active=dev進行組態檔串接,但小編覺得這樣太麻煩,如果沒帶預設環境參數,小編希望自動配置預設,故小編重新調整以下方法與Spring 原生環境配置對接,命名規則如下:

application-{profile}.properties

當我們切割出三項設定後,分別在內部放置環境屬性參數(sea.food.system.environment),當系統啟動時我們可得知目前所配置的參數為哪個設定檔,相關檔名配置如下(詳細資訊請看範例程式碼):

application name sea.food.system.environment
application-dev.properties Sea Food Development ENV
application-staging.properties Sea Food Staging ENV
application-prod.properties Sea Food Production ENV

由於此環境參數最後通過Map集合中的springProfile key進行替換,故我們須在預設的application.properties組態檔中加上取代環境變數的參數,及加上替換的方法在build.gradle中,小編較少使用maven,但一樣也是透過pom.xml進行配置profiles參數,可以進行參考,相關設定如下:

application.properties setting profiles parameter

  spring.profiles.active=@springProfile@
  
  ...
  ...

加入以下取代參數方法在build.gradle 中,以便若無配置系統環境參數依舊會吃預設的profile


  def seaFoodSpringProfile = System.getProperty("profile") ?: "dev"

  println('Build Sea Food System PROFILE : ' + seaFoodSpringProfile)

  bootRun {
      systemProperty 'spring.profiles.active', "${seaFoodSpringProfile}"
  }

  processResources {
      filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [
              springProfile: seaFoodSpringProfile
      ]
  }

通過以上配置方式,我們就可以順利的將Spring的環境參數概念優化到對應的專案自動化構建工具中囉。

Command Line Flow

小編提供以下測試指令及結果提供各位開發者作參考。

Run dev/stag/prod environment application without JAR file

 1. gradle bootRun -D profile=dev
 2. gradle bootRun -D profile=stag
 3. gradle bootRun -D profile=prod

Result sample

 01:27:48.269  INFO 34931 --- [           main] sw.spring.sample.config.SeaFooConfig     : *******************************************************
 01:27:48.270  INFO 34931 --- [           main] sw.spring.sample.config.SeaFooConfig     : *** Sync boot profile : [Sea Food Development ENV] ***
 01:27:48.271  INFO 34931 --- [           main] sw.spring.sample.config.SeaFooConfig     : *******************************************************

Build dev/stag/prod environment JAR boot file without test

1. gradle -Dprofile=dev clean build -x test
2. gradle -Dprofile=stag clean build -x test
3. gradle -Dprofile=prod clean build -x test

Build Jar Result sample

> Configure project :
Build Sea Food System PROFILE : prod

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.8.3/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 4s
6 actionable tasks: 6 executed

Structure

當系統啟動後,會透過擴展的BaseParamFilterReader類別中read()方法,將所有環境變數檔名稱存入org.apache.tools.ant.filters.ReplaceTokens#tokens物件中(HashTable型態物件),此時我們透過命令提示字元進行替換環境參數,命令如下:

1. gradle -Dprofile=dev 
2. gradle -Dprofile=stag
3. gradle -Dprofile=dev

透過Gradle進行傳遞參數至org.apache.tools.ant.filters.ReplaceTokens中名為tokens參數進行過濾取得其對應配置檔,其參數是一種HashTable型態物件,裡面存取專案資源中所有環境變數檔,並透過繼承之ChainableReader介面中的chain()方法進行過濾參數及取得對應環境變數設定檔,若找不到則都取用default的環境變數(application.properties)。

圖一、Spring 環境變數替換流程圖
image

Environment Information Monitor

JVM 設備監測環境資訊
image

image

Sample source

spring-sample-environment

Reference url

使用 spring.profiles.active 及 @profile 注解 动态化配置内部及外部配置

gradle打包spring boot的测试、正式war、jar包


上一篇
[Day - 26] - Spring Swagger之我的SeaFood API 手冊配製方法
下一篇
[Day - 28] - 運用Spring MockMvc 邁向自動化測試之路
系列文
Wow ! There is no doubt about Learn Spring framework in a month.30

尚未有邦友留言

立即登入留言