1 Spring Boot Externalized Configuration
仔細(xì)閱讀 Spring Boot 源代碼會發(fā)現(xiàn)蒙幻,Spring boot application 啟動時會依次在四個路徑尋找配置文件:
在:
- file:config/ 當(dāng)前文件路徑下的 config 目錄
- file: 當(dāng)前文件路徑
- classpath:/config/ 類路徑下的 config 目錄
- classpath:/ 類路徑
第一次逐目錄遍歷尋找尋找如下文件:
- bootstrap.properties
- bootstrap.xml
- bootstrap.yml
- bootstrap.yaml
第二次遍歷尋找如下文件(未指定 active profile 時):
- bootstrap-default.properties
- bootstrap-default.xml
- bootstrap-default.yml
- bootstrap-default.yaml
第三次遍歷尋找如下文件
- application.properties
- application.xml
- application.yml
- application.yaml
第四次遍歷尋找如下文件(未指定 active profile 時)
- application-default.properties
- application-default.xml
- application-default.yml
- application-default.yaml
舉兩個??
- spring boot 應(yīng)用啟動時加載的第一個配置文件是:file:config/bootstrap.properties
- spring boot 應(yīng)用啟動時加載的最后一個配置文件是:classpath:/application.yaml
條件變量有:
- 目錄(file:config/、file:录别、classpath:/config/、classpath:/)
- 系列(bootstrap邻吞、bootstrap-{profile}组题、application、application-{profile}系列)
- 后綴(properties抱冷、xml崔列、yml、yaml)
- 家族(帶 bootstrap 字樣為 bootstrap 家族旺遮,application 亦然)
1.1 同目錄 的 同系列 配置文件赵讯,先加載的優(yōu)先級最高。即 properties 優(yōu)先級最高耿眉,yaml 優(yōu)先級最低
- Spring Boot 應(yīng)用程序啟動的端口是
- 答案:9999
1.2 同系列 的 同后綴 配置文件边翼,先加載的優(yōu)先級最高。即 file:config/ 目錄優(yōu)先級最高鸣剪,classpath:/ 目錄優(yōu)先級最低
- Spring Boot 應(yīng)用程序啟動的端口是
- 答案:10063
1.3 同目錄 的 同后綴 配置文件组底,后加載的優(yōu)先級最高丈积。即 application-{profile}.xxx 優(yōu)先級最高,bootstrap.xxx 優(yōu)先級最低
- Spring Boot 應(yīng)用程序啟動的端口是
- 答案:10002
1.4 Spring Boot 的參數(shù)配置形式 - 驗證前面結(jié)論
參考 官網(wǎng)資料
1.5 一點猜想
- bootstrap 家族優(yōu)先級最高的選手:位于被首先掃描目錄 file:config/ 下的 bootstrap-default.properties
- application 家族優(yōu)先級最低的選手:位于被最后掃描目錄 classpath:/ 下的 application.yaml
- Spring Boot 應(yīng)用程序啟動的端口是
- 答案:10003 bootstrap 家族優(yōu)先級一定低于 application 家族
1.6 總結(jié)
- bootstrap 系列優(yōu)先級一定低于 application 系列
- 所在目錄越先被掃描優(yōu)先級越高
- active profile 文件優(yōu)先級更高
2 Spring Cloud Config
2.1 沒有 Spring Cloud Config 的時候
2.2 使用 Spring Cloud Config 實現(xiàn)配置文件管理
兩個特點
- Externalized 外部化斤寇,配置文件存放在 jar 包外部
- Centralized 中心化桶癣,各種服務(wù)、各種環(huán)境的配置文件都集中放置在一個地方
2.3 優(yōu)先級問題
根據(jù) Spring Cloud 文檔所述:
By default, bootstrap properties (not bootstrap.properties but properties that are loaded during the bootstrap phase) are added with high precedence, so they cannot be overridden by local configuration.
需要區(qū)分兩個概念:
- properties that are loaded during the bootstrap phase:bootstrap 階段加載的配置
- bootstrap.properties:bootstrap.properties/yml 文件中指定的配置
2.4 bootstrap.yml 用處
The bootstrap context uses a different convention for locating external configuration than the main application context. Instead of application.yml (or .properties), you can use bootstrap.yml, keeping the external configuration for bootstrap and main context nicely separate.
一個例子:
spring:
application:
name: foo
cloud:
config:
uri: ${SPRING_CONFIG_URI:http://localhost:8888}
3 經(jīng)驗總結(jié)
3.1 同一個服務(wù)的兩個實例主鍵生成重復(fù)
服務(wù)內(nèi)部采用 SnowFlake 算法生成 ID娘锁,不同的實例需配置不同的 machineId 等作為實例的標(biāo)識牙寞。發(fā)生錯誤時的配置情況如下:
- jar 包內(nèi)部 application.yml 中配置 machineId 參數(shù),不同實例具有相同配置
- jar 包同目錄下 bootstrap.yml 中配置 machineId 參數(shù)莫秆,不同實例配不同的 machineId
我們原本期望 jar 包同目錄 bootstrap.yml 中的 machineId 參數(shù)配置可以優(yōu)先于 jar 包內(nèi)部 application.yml 中的配置间雀,但是根據(jù) Spring Cloud Config 文檔的說明,以及我們自己做的實驗镊屎,可以看到惹挟,bootstrap.yml 在一般參數(shù)中具有低于 application.yml 的優(yōu)先級,所以最終兩個實例都讀到了程序內(nèi)部配置的 machineId缝驳,造成生成了重復(fù) ID连锯。
由于正式環(huán)境只會持有一份配置文件,所以無法將 machineId 放到配置中心用狱,當(dāng)時采用的解決辦法是將 machineId 配置從 jar 包內(nèi)部抹去运怖,使得應(yīng)用只能從 jar 包外部的 bootstrap.yml 讀取 machineId。但是由于服務(wù)內(nèi)部沒有了 machineId夏伊,導(dǎo)致本地都無法啟動服務(wù)摇展。更好的做法為:在 jar 包旁新建 application.yml 配置文件并配置 machineId 參數(shù),借助頂層目錄的 application.yml 的高優(yōu)先級溺忧,覆蓋 jar 包內(nèi)的 machineId 配置