Spring Cloud Config應用篇(九)
一、SpringCloud Config 配置中心
1.1、配置中心說明
SpringCloud Config 伺服器以下簡稱"配置中心"。 Spring Cloud Config 為分散式系統中的外部配置提供伺服器和客戶端支援。通過 Config Server (配置中心)可以管理 Config Client (應用程式)的外部屬性。應用程式可以通過配置 bootstrap.yml,來載入配置中心下指定配置環境的屬性。
1.2、配置中心服務端配置
1.2.1 配置檔案命名規範
-
-
- {label} 是可選的 git 標籤,預設 master;
- {profile}對映到客戶端上的"spring.profiles.active" 或 “spring.cloud.config.profile”; 是可選的環境配置,常見有 local,dev,test,prod;
- {application} 對映到客戶端的"spring.application.name" 或 “spring.cloud.config.name”;
-
/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
1.2.2 配置環境支援
配置中心環境配置支援 git 儲存器,並支援 label 來控制環境配置版本;也支援 svn 儲存器;同時也支援本地配置,可以不使用遠端儲存器。
- git 配置
配置中心 git 儲存器;
uri 是倉庫路徑;
username/password 賬戶/密碼,此處是 GitHub 賬戶密碼;
default-label 是可選的 git 標籤,預設 master;
search-paths 配置檔案所在路徑,全路徑即:https://github.com/niaonao/spring-cloud/doc/config
spring: cloud: config: server: git: uri: https://github.com/niaonao/spring-cloud username: niaonao password: niaonao123456 default-label: master search-paths: /doc/config
- svn 配置
spring: cloud: config: server: svn: uri: default-label: password: username: search-paths:
- native 本地配置
配置中心會讀取本地配置檔案,配置檔案路徑 /src/main/resources,如下圖在resources 下建立配置檔案 /{application}-{profile}.yml
spring: profiles: active: native
二、例項操作
首先建立一個配置中心專案spring-cloud-config
配置spring-cloud-config的配置檔案
server:
port: 9091
eureka:
instance:
hostname: localhost
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/ #指向服務註冊中心的地址
spring:
application:
name: spring-cloud-config
cloud:
config:
server:
git:
uri: https://github.com/ljx958720/synthesisCloudProperties #遠端配置GIT倉庫地址
force-pull: true #強制從遠端GIT倉庫拉取資料到本地
search-paths: /** #配置檔案所在的目錄
#default-label: master
username: ***** #自己的git帳號
password: *** #自己的git密碼
匯入config-server包,然後在啟動類上加入@EnableConfigServer註解
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency>
在git中新建如下內容
然後開啟服務配置中心並訪問
服務端的展示已經講完了,下面講解下客戶端如何呼叫配置資訊以spring-cloud-service專案為例進行解講,在spring-cloud-service中引用config客戶端包
<!--配置中心客戶端包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
然後在git中建立spring-cloud-service的配置檔案
然後在spring-cloud-service中建立bootstrap.yml檔案,這樣載入時就優先載入bootstrap.yml檔案,如果不這樣配置,會出現載入優先順序問題,如果我們要引用外部檔案記得把外部檔案優先順序調高點
spring: cloud: config: discovery: enabled: true service-id: spring-cloud-service #配置conifg的git檔案地址 eureka: instance: hostname: localhost client: serviceUrl: defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/ #指向服務註冊中心的地址
然後建立ConfigController類
然後訪問路徑可以看到可以拿到配置檔案 的資料,這樣說明成功呼叫了遠端git的配置檔案
目前看似一切完美,但是還是有一個問題,動態改變git資料時,服務無法感知,這個我就不測試了,有興趣的可以先去改動git的配置檔案資訊,然後再訪問同樣的介面,會發現瀏覽器顯示的不是最新的資料,如果瞭解Environement的朋友應該知道,這個跟spring有很大的關係,他的每一個Bean的注入都會識別@Value的資訊,如果注入的資訊發生了改變,那麼Bean就要重新去重新整理,所以接下來這塊要做兩件事,第一件就是針對用到這個Bean的快取的地方要加一個@RefreshScope註解,這個註解的作用就是當springconfig配置中心配置重新整理的時候,會自動重新整理當前類的注入的欄位;第二件事就是config沒有提供主動重新整理的機制,所以我們需要在客戶端加入actuator包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
然後在配置中心加入management配置以實現主動重新整理
改變git中配置檔案資訊
因為8080接點發生了變化,所以訪問http://localhost:8080/actuator/refresh介面進行手動重新整理下,看返回結果就知道手動重新整理成功了
然後再次訪問瀏覽器;結果發生了改變,目的雖然達到,但有個問題,如果我這個服務節點有100個,那我不要日了狗的手動重新整理100個節點嗎,不不不,這不是人乾的事
那有沒有更好的解決方法呢,既然config是配置中心的入口,那如果配置發生改變了,我能不能只重新整理配置中心的介面就重新整理了所有服務介面的配置資訊呢,答案是,真的有,那就是訊息匯流排Spring Cloud Bus
2.1、Spring Cloud Bus
Spring cloud bus通過輕量訊息代理連線各個分佈的節點。這會用在廣播狀態的變化(例如配置變化)或者其他的訊息指令。Spring bus的一個核心思想是通過分散式的啟動器對spring boot應用進行擴充套件,也可以用來建立一個多個應用之間的通訊頻道。目前唯一實現的方式是用AMQP訊息代理作為通道,同樣特性的設定(有些取決於通道的設定)在更多通道的文件中。
大家可以將它理解為管理和傳播所有分散式專案中的訊息既可,其實本質是利用了MQ的廣播機制在分散式的系統中傳播訊息,目前常用的有Kafka和RabbitMQ。利用bus的機制可以做很多的事情,其中配置中心客戶端重新整理就是典型的應用場景之一,我們用一張圖來描述bus在配置中心使用的機制。
根據此圖我們可以看出利用Spring Cloud Bus做配置更新的步驟:
- 提交程式碼觸發post給客戶端A傳送bus/refresh
- 客戶端A接收到請求從Server端更新配置並且傳送給Spring Cloud Bus
- Spring Cloud bus接到訊息並通知給其它客戶端
- 其它客戶端接收到通知,請求Server端獲取最新配置
- 全部客戶端均獲取到最新的配置
2.2、使用
在config的客戶端和服務端加入以下包
<!--提供refresh端點進行主動重新整理-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--Spring Cloud Bus-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-kafka</artifactId>
</dependency>
然後在配置中心加入以下配置
服務端配置好了接下來玩客戶端了
接下來重啟專案浪起來
然後和之前一樣修改git的配置資訊
然後訪問http://localhost:9091/actuator/bus-refresh呼叫bus匯流排重新整理
之後再次訪問瀏覽器,會發現所有配置資訊改變了,搞到這裡,終於達到了重新整理一個介面就使所有服務配置更新了,完全。但這是結束吧,不不不,程式設計師的懶是你無法想像的,雖然我們進化到了要重新整理100多個服務接到到現在只用手動重新整理一個介面,但手動一個也是手動呀,自動的總比自己動好吧,所以下面來寫下自動配置
要說自動更新也很簡單,其實就是在git 的webhooks上掛上一個地址,但這有個問題localhost是掛載不進去的
所以要搞一個外網地址進行訪問,我這裡用ngrock映射出一個外網網址,輸入以下命令就能把9091穿透出去
回車如下圖,得到了兩個外網網址
重新在git上新增上外網網址,儲存後這就意味著,如果我們git上配置發生了變化,它就能達到自動幫我們更新的目的,解放手動
修改下git的配置檔案
然後檢視webhooks會報錯,訪問瀏覽器介面也沒有重新整理資料
怎麼解決這問題呢,其實也很簡單,那就是在spring-cloud-config服務中加上monitor包
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-monitor</artifactId> </dependency>
然後採用下面方式遠端重新整理
然後git上的配置也可以改了
再次訪問瀏覽器,手動變自動了
git網址:https://github.com/ljx958720/spring-cloud-config.git
&n