一、瞭解統一配置中心
什麼是統一配置中心?
SpringCloud中的統一配置中心由組件Spring Cloud Config 實現。它是一個高可用的分佈式配置中心。
爲什麼需要統一配置中心?
1.方便維護:在多人協作開發的環境下,常會對同一個配置文件做修改。很容易導致別人更新代碼出現配置文件的衝突,不方便維護。
2.安全與權限:項目中尤其是線上的配置,如數據庫密碼,是不便對普通開發人員公開的。通過統一配置中心,可以對配置和代碼進行隔離。
3.更新配置需要重啓:每次更新配置都需要重啓服務,這樣會導致服務運行效率降低。
統一配置中心都可以解決這些問題。
統一配置中心的架構和流程
通過config-server從遠端git拉取配置到本地git給其他服務使用。
統一配置中心的兩個角色
config-server : 從遠程git拉取配置並且存於本地git庫。當遠程git連接不上,還可以使用本地git中的配置。
config-client : 由本地的服務(如訂單、商品服務等)集成config-client的功能,從config-server獲取其拉取到的配置。
二、實現配置中心服務端
1.引入依賴
新建一個名稱爲config-server(可自定義)的maven工程,引入作爲配置中心服務端需要的依賴spring-cloud-config-server,
同時該工程還是作爲一個eureka的客戶端,因此還需依賴spring-cloud-starter-netflix-eureka-client:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.開啓配置中心功能
在config-server服務的啓動類上使用註解@EnableDiscoveryClient 和 @EnableConfigServer分別開啓eureka客戶端和配置中心服務端:
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
3.配置遠程倉庫地址
嘗試啓動服務
可以發現控制檯輸出需要配置遠程git地址。
因此需要新建遠程git倉庫:
我將訂單服務的配置文件order.yml放到遠程倉庫中:
之後在config-server服務中配置遠程倉庫的地址,用戶名、密碼、要配置文件拉取到的本地文件夾(會自動初始化本地git庫):
之後啓動config-server服務,
console中打印了config-server提供的訪問規則,根據訪問規則可以直接在瀏覽器查看和訪問配置文件。
規則說明:
{/name}指服務名
{profiles}指環境
{label}指git分支
例如在遠程新建分支“temp”,在“temp”分支上新建了order-dev.yml,
那麼訪問規則就是:
{本機ip:config-server服務端口}/{分支名}/{服務名-環境}.yml
http://127.0.0.1:8080/temp/order-dev.yml
要注意的是,即使遠程倉庫中是order.yml,沒有帶有環境名,也需加上任意字符串纔可訪問,
如http://127.0.0.1:8080/order-a.yml
查看確實自動clone了git庫到本地及拉取了遠端配置文件:
三、實現配置中心客戶端
以order服務舉例,實現配置中心客戶端的功能。
首先將準備好的order.dev.yml存入遠程git庫:
在order服務中引入配置中心客戶端需要的依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
因爲要使用configserver從遠程拉取的配置order-yml,所以本地的application.yml中不再需要保留數據源、eureka相關配置,
本地application.yml仍然需保留,但是隻需配置“ 服務名稱、開啓配置中心、配置中心服務端的服務名、配置文件環境 ” 用來向config-server獲取配置:
在啓動order服務後 config-client端將會根據服務名order和環境後綴dev到config-server端找尋配置文件order.dev.yml。
嘗試啓動order服務:
可以發現啓動失敗,找不到數據源信息。
這是因爲服務啓動就會直接在本地的application.yml中找尋數據源配置信息。
解決辦法:可以將本地的application.yml改名爲bootstrap.yml,基於springboot配置文件加載規則,bootstrap.yml中的內容會優先加載,之後再去config-server獲取到遠端配置文件內容後再加載遠程相關配置中如數據源等信息。
爲了查看其中的配置內容是否確實獲取到了,再次啓動之前,編寫一個測試接口:
environment是我在遠端order-dev.yml中的一個配置項,若成功獲取配置,則此接口可以返回envir的內容。
成功啓動後調用接口,可以正常返回該配置內容:
在console中也可以看到啓動服務時獲取配置文件的相關日誌:
四、使用springcloudconfig要注意的一些問題
1、高可用的問題
配置中心客戶端的功能雖然實現了。但是隻是單臺config-server顯然無法是滿足高可用的要求。
在生產環境服務端肯定是需要多啓動幾臺config-server實例的。
2、修改遠程eureka配置引發的問題
在前文中,我啓動了eureka-server的實例端口是8761的默認端口。
假如把eureka-server的啓動端口改爲8762
config-server中連接eureka相應的改爲8762
遠程的配置文件order-dev中也相應的進行修改。
啓動eureka-server、config-server,config-server正常啓動,註冊成功了:
但是啓動order服務時,發現報錯,而且連接config-server獲取配置的url是錯誤的,我config-server端口是8080,爲什麼會這樣?
config-client連接config-server的默認端口是8888,我在order服務中如前文的配置,基於eureka的服務發現,應該用8080連接ureka。爲什麼會走默認端口,導致報錯?
問題原因:
order啓動的第一件事是先去eureka註冊中心找config-server的服務地址,才能通過config-server獲取遠程配置,但我現在還沒有獲取到遠程git上的eureka配置信息,又如何連接eureka-server呢?於是order服務就會走默認的8761連接eureka-server。
原本eureka是使用8761啓動,order服務第一次因爲沒有配置,會通過默認訪問eureka-server端口8761,可以訪問到eureka-server,從eureka-server獲得了config-server的正確地址,所以獲取配置時走config-server的8080端口,一切正常。
現在eureka啓動端口改成8762,order服務因爲沒有eureka配置,仍然走8761訪問eureka-server,就無法連接到eureka,也就無法獲取到註冊在eureka上的config-server地址,只能走默認連接config-server的8888端口,導致訪問了錯誤的8888去連接config-server。
解決: 所以對於eureka-server的訪問配置信息,就不要配置在遠程倉庫了,將遠程倉庫上order-dev.yml中eureka配置信息剪到本地的bootstrap.yml中。讓服務啓動時能正確訪問eureka-server。
3. 刪除遠程eureka配置信息未生效
爲了解決問題2,我已經將遠程倉庫中order-dev.yml文件裏的eureka相關配置移除,將這些信息配置到本地的order服務中。
但是我多次刷新config-server從遠程git拉取到的配置內容,發現配置文件中該eureka相關內容是還是存在:
爲什麼修改沒有生效?
再吃刷新請求配合文件,可以發現拉取了兩個配置文件。
問題產生的原因:
之前在實現config-server的過程中,有說到拉取配置文件的url規則,http://localhost:8080/order-dev.yml這個路徑其實也是符合拉取order.yml的,因此會將order-dev.yml和order.yml都進行拉取並且合併,而在order.yml中其實還存在eureka的配置信息沒有刪除,會被合併。因此出現了刪除oder-dev.yml中內容無效的現象。
解決方法:
那麼是否把order.yml直接刪除最好呢?
並不是,把其中需要刪掉的配置內容刪去即可,order.yml可以保留。
既然order.yml不管在什麼拉取任何環境的配置文件時都會被一同拉取,不如就在需要時將各個環境都需要的公共的配置定義在裏面。這樣也提高了配置的複用性。
五、SpringCloudBus實現動態刷新配置
前面實現了config-server和order服務的config-client,但是修改配置以後,還需要重啓order服務,
還沒有實現修改配置無需重啓服務的功能。
要實現服務運行時動態的刷新配置,就需要引入一個新的springcloud組件:SpringCloudBus ;
配置的動態刷新的實現原理
order服務在啓動後,訪問config-server獲取配置,但在修改了遠端配置後,order服務是不知道的。
因此實現動態刷新配置的關鍵在於如何在修改了遠端配置後,config-server能夠通知到order服務。
怎麼通知呢,通知消息的承載就需要載體,也就是消息隊列,比如RabbitMQ。
這裏要操作消息隊列就需要SpringCloudBus。
configserver和order服務通過消息隊列來傳遞信息,config-server在使用了SpringCloud Bus後會對外提供一個接口,叫做
/bus-refresh。訪問這個接口,config-server就會把更新配置的信息發送到MQ中。
我們希望的是遠端git上修改配置後就能夠訪問這個接口,因此這個接口自然由git來訪問最好。在如Github之類的git服務器基本都有提供WebHook的功能,只要把接口配置進去就可以。當發生修改時,Github就會對WebHook中的配置的接口進行調用。