天天看點

Spring Cloud 微服務之配置中心解決方案

關于配置中心這一篇博文,本來想分很多篇去介紹的,但是仔細想想,覺得太繁複而且啰嗦,是以還是寫一篇介紹其中的核心原理,并不做任何示例,如果想要檢視具體用法可以自行檢視官方文檔或者度娘。因為配置中心太多了,不說其他的Spring Cloud就內建了好幾種架構作為配置中心比如:Spring Cloud Config, Archaiu,Consul, Spring Cloud Zookeeper ,Alibaba Nacos等。每個公司都有不同的選擇,不可能一一的去列舉,重點是掌握核心,當遇到新的配置中心的時候能夠快速入手。

在講解核心原理之前,我們先介紹下為什麼會引入配置中心的子產品。在微服務架構中,一個服務可能被部署在成百上千甚至上萬的節點上(伺服器上),如果将配置全部配置在應用的application.yaml或者application.properties中,一旦我們需要修改某個配置,我們需要手動需修改每一個服務的配置,如果動手一個一個的修改,想想都會頭大吧。當然也可以使用腳本的方式修改,但是如果腳本修改失敗,就會造成有的更新成功,有的更新失敗,最關鍵的是我們不能做到實時更新,需要重新開機應用才能使用最新的配置。而且每個應用維護自己的配置顯得配置冗雜。為了解決該問題,于是提示了配置中心的概念。那麼什麼是配置中心呢?

配置中心顧名思義,就是所有配置的中心。就是我們将所有服務的配置,通過配置中心存儲到資料庫或者其他地方,而應用服務則是從配置中心拉取去配置。在這裡它一般分為服務端和用戶端,服務端用于我們添加修改配置,用戶端用于應用從配置服務拉取配置。一般情況下配置服務分為兩種模式,一種為拉取配置,第二種為推送配置。就是用戶端定時從配置伺服器拉取最新的配置,推送配置則是配置更新後,配置伺服器将更新的配置推送到對應的應用服務。

前面說了一堆的廢話,我想大多數人喜歡看的是如何使用配置中心,而不是配置中心是怎麼來的,寫一個配置中心。下面我們結合Zookeeper和Spring Cloud Config 介紹配置中心的使用。關于Zookeeper,它是一個分布式的,開放源碼的分布式應用程式協調服務,它提供的其中的一個功能就是配置維護,也就是說我們可以将配置存儲在Zookeeper中。下面我們簡單描述Zookeeper在配置中心的使用。

Spring Boot應用中都有一個執行個體名稱即spring.application.name的配置,還有一個spring.profiles.active配置,可以說這兩個配置是配置中心的基礎,也使用這兩個配置從配置中心擷取配置。假如在Zookeeper中配置的根節點為 /config,那麼應用的配置節點可以設定為/config/serviceId/profile/,應用ZooKeeper用戶端監聽節點/config/serviceId/profile/,一旦節點發生變化,會通知給應用服務,應用服務則更改配置為最新的配置。這就是ZooKeeper作為配置中心的基本原理,具體實作跟使用不再這裡不再講解,如果後續使用到ZooKeeper作為配置中心,再補充相關部落格内容。

其他的配置中心我們不再介紹,如果使用到再補充相關使用的博文,其實不管是使用哪個作為配置中心,他們的實作都基本是類似的,下面我們來講述Spring Cloud 配置中心的原理,說到這裡我們不得不回到Spring Boot中,因為Spring Cloud就是基于Spring Boot為核心。在前面Spring Boot原理一篇我們介紹了Spring Boot 建立執行個體的原理,沒有有講解關于配置的原理。這裡我們簡單的介紹Spring Cloud 是如何結合Spring Boot實作配置中心的。同樣是SpringApplication提供的run方法内部代碼如下:

public ConfigurableApplicationContext run(String... args) {
    ......
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    ......
    SpringApplicationRunListeners listeners = getRunListeners(args);
    listeners.starting();
    try {
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
        .......
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
    configureIgnoreBeanInfo(environment);
    Banner printedBanner = printBanner(environment);
    ......
}
           

上面的代碼中prepareEnvironment方法用于為Spring Boot運作環境提供配置,在Spring中所有的配置最終由Environment執行個體管理。我們檢視prepareEnvironment方法的源碼如下:

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments) {
    // Create and configure the environment
    ConfigurableEnvironment environment = getOrCreateEnvironment();
    //解析和配置application.properties中的配置和運作時傳入的參數配置
    configureEnvironment(environment, applicationArguments.getSourceArgs());
    //在SpringApplicationRunListeners 解析和處理配置
    listeners.environmentPrepared(environment);
    bindToSpringApplication(environment);
    if (!this.isCustomEnvironment) {
        environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
    }
    ConfigurationPropertySources.attach(environment);
    return environment;
}
           

在上面的代碼中,一部分是處理配置檔案中的配置,另一部分是通過SpringApplicationRunListeners 處理配置,SpringApplicationRunListeners 是配置中心的基礎,用戶端可以通過實作SpringApplicationRunListeners 的environmentPrepared方法,在該方法中可以将配置設定到Environment執行個體中。不同的配置中心比如Zookeeper,Spring Cloud Config、Alibaba Nacos等有着不同的實作。實作的基礎則是SpringApplicationRunListeners 接口。

本篇部落格隻是介紹Spring Cloud 配置中心的原理,以及實作方式,并不介紹配置中心的使用,後續在介紹Spring Cloud Alibaba時會簡單的介紹Alibaba Nacos配置中心的使用。不管怎麼說配置中心的實作都是萬變不離其宗,包括服務的拉取、推送和更新。而這些又都是結合Spring Boot進行的。上面的兩部分代碼是核心。

繼續閱讀