1. 程式人生 > >Spring-Cloud-Config 多服務公共檔案配置

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

ServiceB.properties中配置兩遍,這樣的話,萬一以後服務發現(Eureka)的配置改了,就要每個服務的配置檔案都要去修改了,這樣非常難以維護。所以想到了利用公共檔案方法,現在在這裡簡單闡述一下如何配置。(下面例子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']]]

參考資料:

稿畢!