SpringCloudNetflix學習和實踐——統一配置中心

一、瞭解統一配置中心

什麼是統一配置中心?

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中的配置的接口進行調用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章