一、什么是配置中心?
微服務意味着要將單體應用中的業務拆分成一個個子服務,這些服務都需要必要配置信息才能運行,每個微服務都包含一個類似application.yml的配置文件,單個管理顯得極其麻煩,於是集中式的管理思想誕生了,該思想旨在微服務模塊之外提供一個集中化的外部配置支持平台,為每個微服務提供配置支持,這個平台稱為配置中心。
SpringCloudConfig是SpringCloud集成的一種配置中心服務框架,分為客戶端和服務端兩部分。服務端叫分布式配置中心,它是一個獨立的微服務應用,用於連接配置服務器並向客戶端提供配置信息,服務器默認采用git來存儲配置信息。客戶端也就是其它的一個個微服務,它通過指定的服務端來管理應用資源,在啟動時從服務端獲取配置信息。以下是配置中心架構圖
二、Config配置中心搭建
搭建配置中心步驟:
1、創建配置中心倉庫:按照配置中心架構圖分析,我們首先需要注冊一個git賬號,創建一個配置中心倉庫Repository,創建一個config-test.yml配置文件,記錄下git倉庫地址。
2、創建配置中心微服務模塊步驟:
a.服務模塊引入config-server包
<dependency> <groupId>org.springframework.cloud</groupid> <artifactid>spring-cloud-config-server</artifactId> </ dependency>
b.配置application.yml文件:代碼示例如下,表示配置中心獲取配置信息時從git@github.com:xxxx/springcloud-config.git/springcloud-config路徑下獲取,選擇分支為master分支。
server: port: 3344 spring: application: name:cloud-config-center #注冊進Eureka服務器的微服務名
cloud: config: server: git: uri: git@github.com:xxxx/springcloud-config.git #GitHub上面的git倉庫地址 search-paths: - springcloud-config #搜索目錄路徑 label: master #倉庫分支
eureka : client: service-url: defaultzone: http://localhost:8099/eureka #注冊該模塊到eureka注冊中心
c.主啟動類上增加@EnableConfigServer注解激活配置中心功能。
完成以上3步,啟動時就可以通過配置中心去獲取git上的配置文件了,在瀏覽器上訪問http://localhost:3344/master/config-test.yml即可獲取。配置中心將配置文件以REST接口的形式暴露供客戶端使用,需要注意的是,官方提供了幾種獲取配置的規則(根據該規則,要求配置文件的名稱應該按照規則格式來書寫),具體如下:
URL格式 | 說明 |
/{label}/{application}-{profile}.yml |
label表示分支,application表示服務名稱,profile表示環境(test、prod、dev) |
/{application}-{profile}.yml |
application表示服務名稱,profile表示環境(test、prod、dev) |
/{application}/{profile}[/{label}] |
label表示分支(可選),application表示服務名稱,profile表示環境(test、prod、dev) |
/{label}/{application}-{profile}.properties |
label表示分支,application表示服務名稱,profile表示環境(test、prod、dev) |
三、客戶端從配置中心獲取配置文件
前面講述了如何創建配置中心服務模塊,以及配置中心從git獲取配置文件的方式,接下來講解客戶端又是如何從配置中心獲取配置文件的。
配置中心服務模塊引入的jar包是spring-cloud-config-server,而客戶端需要引入的是spring-cloud-starter-config。代碼如下
<dependency> <groupId>org.springframework.cloud</groupid> <artifactid>spring-cloud-starter-config</artifactid> </ dependency>
在進行客戶端配置文件編輯之前,我們先了解一下bootstrap.yml配置文件和application.yml文件的區別。applocation.yml文件時是用戶級別的資源配置文件,而bootstrap.yml是系統級別的,優先級更高,在加載時bootstrap要比application先加載。在springCloud啟東時會創建一個bootstrap上下文,作為spring應用Application上下文的父級,在初始化時Bootstrap上下文會從外部源加載配置屬性。因此在創建客戶端模塊時我們先選擇使用bootstrap.yml文件,創建和配置方式與application.yml一樣。
以下是bootstrap.yml的示例代碼:
server: port: 3355 spring: application: name:cloud-config-client #注冊進Eureka服務器的微服務名 cloud: config: label: master #分支名稱 name: config #配置文件名稱 profile: dev #讀取后綴名稱 uri: //localhost:3344/ #配置中心地址 eureka : client: service-url: defaultzone: http://localhost:8099/eureka #注冊該模塊到eureka注冊中心
進行如上配置之后,接下來創建一個從配置中心上獲取配置信息的Controller,示例代碼如下:
@RestController public class ConfigClientController { value("${config.info}") /*讀取配置文件信息,系統會根據bootstrap配置文件里的config信息從注冊中心獲取配置文件信息*/ private string configInfo; GetMapping("/configInfo") public string getConfigInfo() { return configInfo; } }
完成以上步驟后,啟動配置中心和客戶端,訪問http://localhost:3355/configInfo,系統將會根據bootstrap配置信息從注冊中心獲取git配置文件。
四、分布式配置文件動態刷新
完成前面的客戶端和配置中心模塊開發后,在git倉庫中修改配置文件的內容,分別訪問http://localhost:3344/master/config-test.yml 和 http://localhost:3355/configInfo ,通過注冊中心3344訪問能夠及時的獲取到最新更改的內容,而通過客戶端3355返回的還是最初的內容,也就是說3355客戶端沒能獲取到最新的更改內容(除非重啟客戶端)。真實情況下,運維工程師可能會根據需求調整配置文件內容,但每次調整都不可能要求重啟每一個客戶端模塊,因此需要修改3355模塊對配置文件進行監控,實時刷新最新文件。
客戶端實現實時刷新的步驟:
1、引入actuator監控工具包:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、修改yml暴露監控端點:
#暴露監控端點 management: endpoints:
web:
base-path:/actuator #actuator提供的api接口根路徑 exposure: include: "*" #需要開放的端點,默認只打開health、info,*表示所有
exclude: #需要排除的端點
3、在業務類Controller上增加@RefreshScope注解:
@RestController @Refreshscope public class ConfigClientController { value("${config.info}") /*讀取配置文件信息,系統會根據bootstrap配置文件里的config信息從注冊中心獲取配置文件信息*/ private string configInfo; GetMapping("/configInfo") public string getConfigInfo() { return configInfo; } }
4、通知客戶端配置文件需要刷新:
a.手動刷新端點:發送post請求到 http://localhost:3355/actuator/refresh 通知3355客戶端配置文件已經改變,客戶端收到該請求后動態刷新配置文件。
b.自動刷新端點:結合git網絡鈎子程序,在配置文件修改后,git自動post訪問客戶端暴露的端點實現自動刷新。或者結合消息總線SpringCloudBus完成自動刷新。
到此,從客戶端到配置中心的配置文件動態獲取功能已完成。