Spring Cloud統一配置中心(Config)

參考:https://www.jianshu.com/p/997600098e6c   

        在普通單體應用,我們常使用配置文件(application(*).properties(yml))管理應用的所有配置。這些配置文件在單體應用中非常勝任其角色,並沒有讓我們感覺到有頭疼的地方。但隨着微服務框架的引入,微服務數量就會在我們產品中不斷增加,之前我們重點考慮的是系統的可伸縮、可擴展性好,但隨之就是配置管理的問題就會一一暴露出來。起初微服務器各自管各自的配置,在開發階段並沒什麼問題,但到了生產環境管理就會很頭疼,如果要大規模更新某項配置,困難就可想而知。

        爲此,在分佈式系統中,Spring Cloud提供一個Config子項目,該項目核心就是配置中心,通過一個服務端和多個客戶端實現配置服務。我們可使用配置服務器集中的管理所有服務的各種環境配置文件。配置服務中心默認採用Git的方式進行存儲,因此我們很容易部署修改,並可以對環境配置進行版本管理。Spring Cloud Config具有中心化、版本控制、支持動態更新和語言獨立等特性。其特點是:

  • 提供服務端和客戶端支持(Spring Cloud Config Server和Spring Cloud Config Client);
  • 集中式管理分佈式環境下的應用配置;
  • 基於Spring環境,實現了與Spring應用無縫集成;
  • 可用於任何語言開發的程序;
  • 默認實現基於Git倉庫(也支持SVN),從而可以進行配置的版本管理;

Spring Cloud Config的結構圖如下:

 

        從圖中可以看出Spring Cloud Config有兩個角色(類似Eureka): Server和Client。Spring Cloud Config Server作爲配置中心的服務端承擔如下作用:

  • 拉取配置時更新Git倉庫副本,保證是配置爲最新;
  • 支持從yml、json、properties等文件加載配置;
  • 配合Eureke可實現服務發現,配合Cloud Bus(這個後面我們在詳細說明)可實現配置推送更新;
  • 默認配置存儲基於Git倉庫(可以切換爲SVN),從而支持配置的版本管理.

而對於,Spring Cloud Config Client則非常方便,只需要在啓動配置文件中增加使用Config Server上哪個配置文件即可。

構建Config-Server(idea)

pom如下:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

啓動類:

@SpringBootApplication
@EnableConfigServer
public class SpringCloundConfigDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloundConfigDemoApplication.class, args);
    }
}

其中增加了@EnableConfigServer。

application.properties:

server.port=8890
spring.application.name=server-config
spring.cloud.config.server.git.uri=https://gitee.com/skyLogin/SpringCloundConfigGit.git
spring.cloud.config.server.git.username=登錄名
spring.cloud.config.server.git.password=密碼

這裏最重要的是需要配置Git倉庫的地址及登錄用戶名和口令。

我們在SpringCloundConfigGit倉庫中提交如下文件
user.properties:

project.name = sky

user-dev.properties:

project.description = dev-description

啓動測試:

{
    "name": "user",
    "profiles": ["dev"],
    "label": null,
    "version": "9bc698347dcb4e82e1c8fc631d7409cc3f0e6a65",
    "state": null,
    "propertySources": [{
        "name": "https://gitee.com/skyLogin/SpringCloundConfigGit.git/user-dev.properties",
        "source": {
            "project.description": "dev-description"
        }
    }, {
        "name": "https://gitee.com/skyLogin/SpringCloundConfigGit.git/user.properties",
        "source": {
            "project.name": "sky"
        }
    }]
}

        這裏可以看到,我們提交到Git中的配置文件已經能夠被server-config正確的讀取到。
 

構建config-client

        config-client可以是任何一個基於Spring boot的應用,這裏爲了講解方便,我們構建一個非常簡單的web工程。我們的config-client項目需要引入對spring-cloud-starter-config的依賴,如下:

 

pom:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

一個標準的Spring Boot啓動類:啓動類

@SpringBootApplication
public class SpringCloundConfigClientDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloundConfigClientDemoApplication.class, args);
    }
}

這個測試Controller主要就是驗證我們可以從Git倉庫中獲取配置內容。編寫測試Controller

@RestController
public class ConfigController {
    @Value("${project.name}")
    String name;

    @Value("${project.description}")
    String description;
    @RequestMapping("/config/get/message")
    public String getMessage() {
        return name + " - " + description;
    }
}

這裏編寫的配置文件名稱爲:bootstrap.properties,內容如下:編寫配置文件

server.port=8891

spring.application.name=user
spring.cloud.config.profile=dev
spring.cloud.config.uri= http://localhost:8890/

定義了微服務的名稱和profile以及配置服務器的地址。  

注意: 這些配置不能夠配置在application.properties文件中,因爲在Spring Boot啓動時有引導上下文應用上下文的概念,只有將配置服務器信息定義在引導上下文中,才能夠從配置服務器中獲取到配置信息。否則,服務啓動時會報找不到變量定義的錯誤。

啓動測試

說明,我們的config-client已經成功從server-config上獲取到配置的數據了。


Config Server配置文件映射關係

Config Server啓動以後,我們可以通過它暴露的端點獲取配置文件內容,http請求地址與配置文件映射關係如下:

# 映射{application}-{profile}.properties文件
/{application}/{profile}/[{label}]
/{label}/{application}-{profile}.properties
/{application}-{profile}.properties
/{label}/{application}-{profile}.yml
/{application}-{profile}.yml

{application}通常使用微服務名稱,對應Git倉庫中文件名的前綴;
{profile}對應{application}-後面的dev、pro、test等;
{label}對應Git倉庫的分支名,默認爲master。

Config Client從Config Server中獲取配置數據的流程:

1.Config Client 啓動時,根據 bootstrap.properties 中配置的應用名稱(application)、環境名(profile)和分支名(label),向 Config Server 請求獲取配置數據;
2.Config Server 根據 Config Client 的請求及配置,從Git倉庫(這裏以Git爲例)中查找符合的配置文件;
3.Config Server 將匹配到的Git倉庫拉取到本地,並建立本地緩存;
4.Config Server 創建Spring的 ApplicationContext 實例,並根據拉取的配置文件, 填充配置信息,然後將該配置信息返回給 Config Client ;
5.Config Client 獲取到 Config Server 返回的配置數據後,將這些配置數據加載到自己的上下文中。同時,因爲這些配置數據的優先級高於本地Jar包中的配置,因此將不再加載本地的配置。

那麼,Config Server 又是如何與Git倉庫中的配置文件進行匹配的呢?通常,我們會爲一個項目建立類似如下的配置文件:

mallweb.properties : 基礎配置文件;
mallweb-dev.properties : 開發使用的配置文件;
mallweb-test.properties : 測試使用的配置文件;
mallweb-prod.properties : 生產環境使用的配置文件;

當我們訪問 Config Server 的端點時,就會按照如下映射關係來匹配相應的配置文件:

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

上面的Url將會映射爲格式爲:{application}-{profile}.properties(yml)的配置文件。另外, label 則對應Git上分支名稱,是一個可選參數,如果沒有則爲默認的 master 分支。

而 Config-Client 的 bootstrap.properties 配置對應如下:

spring.application.name application;
spring.cloud.config.profile profile;
spring.cloud.config.label label.

Config Server健康狀況

Config Server自帶了健康狀況指示器,暴露的endpoint爲/health,用於檢查配置的倉庫是否可用。對於文中的Config Server,請求http://localhost:8181/health返回如下結果

{
    "status": "UP"
}

配置刷新

Config-Client中提供了一個 refresh 端點來實現配置文件的刷新。要想使用該功能,我們需要在Config-Client的pom.xml文件中增加以下依賴:

    org.springframework.boot
    spring-boot-starter-actuator

這樣,當修改配置文件並提交到Git倉庫後,就可以使用: http://localhost:8080/refresh 刷新本地的配置數據。但是,最好的方式還是和Spring Cloud Bus進行整合,這樣才能實現配置的自動分發,而不是需要手工去刷新配置。

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