Spring-Cloud-Config 多服務公共檔案配置
問題描述
基於 spring-cloud微服務開發,通常會配置一個Spring-Cloud-Config-Server,各個客戶端會通過Spring-Cloud-Config-Server從配置倉庫拉取自己服務的配置,如何配置Spring-Cloud-Config-Server,可以參考本人前段時間寫的文章“”
。
假如客戶端Service-A 對應的配置檔案為ServiceA.properties,假如客戶端Service-B對應的配置檔案為ServiceB.properties,如果兩個服務都需要使用同一個服務發現(Eureka)的配置,豈不是要在ServiceA.properties
Spring-Cloud-Config-Server
都是使用本地配置方式)。
方法一:
在配置倉庫的根目錄建立一個子目錄,(注:子目錄最好不要用config作為目錄名稱,為什麼,看下文),然後建立application.properties作為公共檔案。ServiceA-dev.properties、ServiceB-dev.properties作為各個客戶端服務的單獨配置檔案。
客戶端ServiceA-dev.properties的配置:
spring.application.name=ServiceA
spring.cloud.config.uri=http://localhost:8762/config-server
spring.cloud.config.failFast=true
spring.cloud.config.profile=dev
客戶端ServiceB-dev.properties的配置:
spring.application.name=ServiceB spring.cloud.config.uri=http://localhost:8762/config-server spring.cloud.config.failFast=true spring.cloud.config.profile=dev
啟動資訊如下:
INFO 8754 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource [name='configService', propertySources=[MapPropertySource [name='classpath:/config1/ServiceA-dev.properties'], MapPropertySource [name='classpath:/config1/application.properties']]]
可以在日誌上看到讀取了兩個配置檔案資訊了。
客戶端在啟動的時候,如果在單獨配置檔案中,找不到配置項,就會到公共配置檔案中獲取。單獨配置檔案配置項的優先順序大於公共公共配置檔案的配置項。這裡說明一下為什麼子目錄最好不要用config作為目錄名稱,因為如果用了config作為字幕了名稱,這樣Spring-Cloud-Config-Server在啟動的時候,就會優先讀取
config子目錄下的application.properties。原因是Spring Boot 提供的 SpringApplication 類會搜尋並載入 application.properties 檔案來獲取配置屬性值。SpringApplication 類會在下面位置搜尋該檔案。(優先順序從上到下)
- 當前目錄的“/config”子目錄。
- 當前目錄。
- classpath 中的“/config”包。
- classpath
通常Spring-Cloud-Config-Server的配置都是單獨配置的,不要跟客戶端使用同一些配置項,所以這就是為什麼
子目錄最好不要用config作為目錄名稱的原因。
方法二:
如果你非得要用config作為子目錄的目錄名稱,那你的公共檔案就不要用application作為公共檔案的名稱咯,如何進行公共檔案配置呢,開始搜尋了好多文章,有一個文章是這樣配置的:
例如:
service-a
客戶端的 bootstap.yml
:
spring:
application:
name: service-a, datasorce
service-b
客戶端的 bootstap.yml
:
spring:
application:
name: service-b, datasorce
但是啟動客戶端專案的時候,壓根就會報錯:錯誤資訊如下
Caused by: java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.String
at com.netflix.config.ConfigurationBasedDeploymentContext.getValueFromConfig(ConfigurationBasedDeploymentContext.java:329) ~[archaius-core-0.7.4.jar:0.7.4]
at com.netflix.config.ConfigurationBasedDeploymentContext.getValue(ConfigurationBasedDeploymentContext.java:349) ~[archaius-core-0.7.4.jar:0.7.4]
後來怎麼去解決都行不通的,其實想想就知道用spring.application.name來配置多個配置檔名,這樣的話,服務發現(eureka)是利用spring.application.name作為application Name的,這樣設定一個客戶端服務有兩個服務名,肯定是不恰單的。
如何去配置才可以呢?其實可以在spring.cloud.config.name這裡去配置多個配置檔名,這裡的common.properties就是公共配置檔案。
spring.application.name=ServiceA
spring.cloud.config.uri=http://localhost:8762/config-server
spring.cloud.config.name=ServiceA,common
spring.cloud.config.failFast=true
spring.cloud.config.profile=dev
這樣啟動的時候可以在日誌上看到讀取了兩個配置檔案資訊了
INFO 8736 --- [ main] b.c.PropertySourceBootstrapConfiguration : Located property source: CompositePropertySource [name='configService', propertySources=[MapPropertySource [name='classpath:/config/ServiceA-dev.properties'], MapPropertySource [name='classpath:/config/common.properties']]]
參考資料:
稿畢!