Spring Cloud Config
簡介
Spring Cloud Config是Spring Cloud團隊創建的一個全新項目,用來爲分佈式系統中的基礎設施和微服務應用提供集中化的外部配置支持,它分爲服務端與客戶端兩個部分。其中服務端也稱爲分佈式配置中心,它是一個獨立的微服務應用,用來連接配置倉庫併爲客戶端提供獲取配置信息、加密/解密信息等訪問接口;而客戶端則是微服務架構中的各個微服務應用或基礎設施,它們通過指定的配置中心來管理應用資源與業務相關的配置內容,並在啓動的時候從配置中心獲取和加載配置信息。Spring Cloud Config實現了對服務端和客戶端中環境變量和屬性配置的抽象映射,所以它除了適用於Spring構建的應用程序之外,也可以在任何其他語言運行的應用程序中使用。由於Spring Cloud Config實現的配置中心默認採用Git來存儲配置信息,所以使用Spring Cloud Config構建的配置服務器,天然就支持對微服務應用配置信息的版本管理,並且可以通過Git客戶端工具來方便的管理和訪問配置內容。當然它也提供了對其他存儲方式的支持,比如:SVN倉庫、本地化文件系統。
在本文中,我們將學習如何構建一個基於Git存儲的分佈式配置中心,並對客戶端進行改造,並讓其能夠從配置中心獲取配置信息並綁定到代碼中的整個過程。
快速入門 【Dalston版】
準備配置倉庫
準備一個git倉庫,可以在碼雲或Github上創建都可以。比如本文準備的倉庫示例:https://github.com/13849141963/spring-config-file
假設我們讀取配置中心的應用名爲springcloud-config
,那麼我們可以在git倉庫中該項目的默認配置文件application-dev.properties:[開發環境]
configFile=configFile dev version 1
爲了演示加載不同環境的配置,我們可以在git倉庫中再創建兩個環境的配置文件application-test.properties: [測試環境]
configFile=configFile test version 1
application-prod.properties:[生產環境]
configFile=configFile prod version 1
構建配置中心
通過Spring Cloud Config來構建一個分佈式配置中心非常簡單,只需要三步:
1、創建一個基礎的Spring Boot工程,命名爲:springcloud-config-server,並在pom.xml
中引入下面的依賴:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2、在application.properties
中添加配置服務的基本信息以及Git倉庫的相關信息,例如:
spring.application.name=springcloud-config-server
server.port=8080
# 配置git倉庫地址
spring.cloud.config.server.git.uri=https://github.com/13849141963/spring-config-file/
# 配置倉庫的分支
spring.cloud.config.label=master
# 配置倉庫路下的相對搜索位置.可以配置多個
spring.cloud.config.server.git.search-paths=respoitory
# 訪問git倉庫的用戶名
spring.cloud.config.server.git.username=13849141963
# 訪問git倉庫的用戶密碼 如果Git倉庫爲公開倉庫,可以不填寫用戶名和密碼,如果是私有倉庫需要填寫
spring.cloud.config.server.git.password=********
3、創建Spring Boot的程序主類,並添加@EnableConfigServer
註解,開啓Spring Cloud Config的服務端功能。
@EnableConfigServer
@SpringBootApplication
public class SpringcloudConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudConfigServerApplication.class, args);
}
}
到這裏,使用一個通過Spring Cloud Config實現,並使用Git管理配置內容的分佈式配置中心就已經完成了。我們可以將該應用先啓動起來,確保沒有錯誤產生。完成了這些準備工作之後,我們就可以通過瀏覽器、POSTMAN或CURL等工具直接來訪問到我們的配置內容了。訪問配置信息的URL與配置文件的映射關係如下:
- /{application}/{profile}[/{label}]
- /{application}-{profile}.yml
- /{label}/{application}-{profile}.yml
- /{application}-{profile}.properties
- /{label}/{application}-{profile}.properties
上面的url會映射{application}-{profile}.properties
對應的配置文件,其中{label}
對應Git上不同的分支,默認爲master。我們可以嘗試構造不同的url來訪問不同的配置內容,比如,要訪問master分支,config-client應用的dev環境,就可以訪問這個url:http://10.0.45.103:8080/spring-config-file/prod,http://10.0.45.103:8080/spring-config-file/test,http://10.0.45.103:8080/spring-config-file/test,並獲得如下返回:
{
"name":"spring-config-file",
"profiles":[
"test"
],
"label":master,
"version":null,
"state":null,
"propertySources":[
{
"name":"https://github.com/13849141963/spring-config-file/respoitory/application-test.properties",
"source":{
"config-file":"configFile test version 1"
}
},
{
"name":"https://github.com/13849141963/spring-config-file/respoitory/application-dev.properties",
"source":{
"config-file":"configFile dev version 1"
}
},
{
"name":"https://github.com/13849141963/spring-config-file/respoitory/application-prod.properties",
"source":{
"config-file":"configFile prod version 1"
}
}
]
}
我們可以看到該Json中返回了應用名:spring-config-file,環境名:dev,分支名:master,以及test環境,dev環境和prod環境的配置內容。
通過啓動配置服務器springcloud-config-server的控制檯中輸出了下面的內容,配置服務器在從Git中獲取配置信息後,會存儲在springcloud-config-sever的文件系統中,實質上springcloud-confi-server是通過git clone命令將配置內容複製了一份在本地存儲,然後讀取這些內容並返回給微服務應用進行加載。
Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@110b791: startup date [Mon Nov 05 19:17:14 CST 2018]; root of context hierarchy
Adding property source: file:/C:/Users/ADMINI~1/AppData/Local/Temp/config-repo-4125257711968764934/respoitory/application-dev.properties
Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@110b791: startup date [Mon Nov 05 19:17:14 CST 2018]; root of context hierarchy
conf ig-server通過Git在本地倉庫暫存,可以有效防止當Git倉庫出現故障而引起無法加載配置信息的情況。我們可以通過斷開網絡,再次發起http://localhost:7001/didispace/prod/config-label-test請求,在控制檯中可輸出如下內容。可以看到,springcloud-config-server提不無法從遠程獲取該分支內容的報錯信息:Could not pull remote for config-label-test,但是它依然會爲該請求返回配置內容,這些內容源於之前訪問時存於springcloud-config-server本地文件系統中的配置內容。
構建客戶端
在完成了上述驗證之後,確定配置服務中心已經正常運作,下面我們嘗試如何在微服務應用中獲取上述的配置信息。
1、創建一個Spring Boot應用,命名爲springcloud-config-client
,並在pom.xml
中引入下述依賴:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.13.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2、創建bootstrap.yml
配置,來指定獲取配置文件的config-server-git
位置,例如:
spring.application.name=springcloud-config-client
# 指明遠程倉庫的分支
spring.cloud.config.label=master
# dev開發環境配置文件 test測試環境 pro正式環境
spring.cloud.config.profile=dev
# 配置中心config-server的地址
spring.cloud.config.uri=http://10.0.45.103:8080/
server.port=7001
上述配置參數與Git中存儲的配置文件中各個部分的對應關係如下:
- spring.application.name:對應配置文件規則中的
{application}
部分 - spring.cloud.config.profile:對應配置文件規則中的
{profile}
部分 - spring.cloud.config.label:對應配置文件規則中的
{label}
部分 - spring.cloud.config.uri:配置中心
config-server
的地址
這裏需要格外注意:上面這些屬性必須配置在bootstrap.properties中,這樣config-server中的配置信息才能被正確加載。
3、創建 controller測試獲取遠程配置文件服務器中的數據
@RestController
public class TestGetConfigController {
@Value("${configFile}")
String configFile;
@RequestMapping(value = "/configFile")
public String getConfigFile(){
return configFile;
}
}
4、啓動類
@SpringBootApplication
public class SpringcloudConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudConfigClientApplication.class, args);
}
}
在完成了上面你的代碼編寫之後,讀者可以將springcloud-config-server、springcloud-config-client都啓動起來,然後訪問http://10.0.45.103:7001/getConfigFile ,我們可以看到該端點將會返回從git倉庫中獲取的配置信息:
configFile=configFile dev version 1
這就說明,springcloud-config-client從springcloud-config-server獲取了config-file的屬性,而springcloud-config-server是從git倉庫讀取的,如圖:
代碼示例
項目github地址:[email protected]:13849141963/spring-cloud.git
具體工程說明如下:
- 基於Git倉庫的配置中心:spring-config-file github地址:[email protected]:13849141963/spring-config-file.git
- 配置中心客戶端:springcloud-config-client
- 配置中心服務端:springcloud-config-server
基礎架構:
在動手實踐了上面關於Spring Cloud Config的基礎入門內容之後,在這裏我們深入理解一下它是如何運作起來的。下圖所示的萣上一節我們所構建案例的基本結構其中,主要包含下面幾個要素。
服務端:
- 遠程Git倉庫:用來存儲配置文件的地方,上例中我們用來存儲計劃應用名爲 didispace 的多環境配置文件! didispace-{profile} .properties.
- Config Server:這是我們上面構建的分佈式配置中心,springcloud-config-server工程,在該工程中指定了所要連接的Git倉庫位置以及賬戶、密碼等連接信息。
- 本地Git倉庫:在springcloud-config-server的義件系統中,每次客戶端請求獲取配罝信息時,springcloud-config-server從Git倉庫中獲取最新配置到本地,然後在本地Git倉庫中讀取並返回。 當遠程倉庫無法獲取時,直接將本地內容返回。
- Service A、 Service B:具體的微服務應用,它們指定了 spriongcloud-config-server的地址,從而實現從外部化獲取應用自己要只的配置信息。這些應用在啓動的時候,會向springcloud-config-server請求獲取配罝信息來進行加載
客戶端: 應用從配置管理中獲取配置信息遵從下面的執行流程:
1、應用後動時,根據 bootstrap. properties中配置的應用名{ application},壞境名{profile}、分支名{label},向ConfigServer請求獲取配置信息
2、CmifigServer根據自己維護的Git倉庫信息和客戶端傳遞過來的配置定位信息去査找配置信息。
3、通過git clone命令將找到的配置信息下載到Config Server的文件系統中。
4、Config Server 創建 Spring 的 ApplicationContent 實例,並從Git 本地倉庫中加載配置文件,最後將這些配置內容讀取出來返回給客戶端應用。
5、客戶端應用在獲得外部配置文件後加載到客戶端的 ApplicationContext實例,該配置內容的優先級高於客戶端Jar包內部的配置內容,所以在ja i包中重複的內容將不再被加載。
Config Server巧妙地通過git clone將配罝信息存於本地,起到了緩存的作用,即使當Git服務端無法訪問的時候,依然可以取Config Server中的緩存內容進行使用。