天天看點

七. SpringCloud服務配置

1. SpringCloud Config概述

1.1 分布式系統面臨的配置問題

微服務意味着要将單體應用中的業務拆分成一個一個子服務,每個服務的粒度相對較小,是以系統中會出現大量的服務。由于每個服務都需要必要的配置才能運作,是以一套集中式的,動态的配置管理設施是必不可少的。

SpringCloud提供了Config Server來解決這個問題,否則我們每一個微服務自己帶着一個application.yml,上百個配置檔案的管理會令人頭疼。

1.2 是什麼

如圖,服務配置中心從遠端讀取配置檔案,然後用戶端服務再通過服務配置中心讀取配置。

七. SpringCloud服務配置

SpringCloud Config為微服務架構中的微服務提供集中化的外部配置支援,配置伺服器為 各個不同微服務應用 的所有環境提供了一個 中心化的外部配置 。

SpringCloud Config分為服務端和用戶端兩部分:

  • 服務端也稱為 分布式配置中心,它是一個獨立的微服務應用 ,用來連接配接配置伺服器并為用戶端提供擷取配置資訊,加密/解密資訊等通路接口,将配置資訊以REST接口的形式暴露給用戶端(用戶端可以用REST風格方式讀取到該配置資訊)。
  • 用戶端則是通過指定的配置中心來管理應用資源,以及與業務相關的配置内容,并在啟動的時候從配置中心擷取和加載配置資訊。配置伺服器預設采用git來存儲配置資訊,這樣就有助于對環境配置進行版本管理,并且可以通過git用戶端工具來友善的管理和通路配置内容。
1.3 作用
  • 集中管理配置檔案
  • 不同環境不同配置,動态化的配置更新,分環境比如dev/test/prod/beta/release
  • 運作期間動态調整配置,不再需要在每個服務部署的機器上編寫配置檔案,服務會向配置中心同意拉取配置自己的資訊
  • 當配置發生改變時,服務不需要重新開機即可感覺到配置的變化并應用新的配置
  • 将配置資訊以REST接口的形式暴露 (post/crul通路重新整理即可)
1.4 與GitHub整合配置

由于SpringCloud Config預設使用Git來存儲配置檔案(也有其他方式,比如支援SVN和本地檔案),但最推薦還是Git,而且使用的是http/https的通路形式。

2. Config 服務端配置與測試

2.1 Gitee倉庫

在Gitee上建立一個用作配置中心的新倉庫,并克隆到本地開發硬碟目錄

然後根據建立的Git位址,将Gitee上的倉庫克隆到本地

git clone https://gitee.com/mp2333/springcloud-config.git
           
2.2 建Module

建立Module:cloud-config-center-3344作為配置中心微服務

在其POM檔案中引入服務配置中心的依賴:

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

修改其配置檔案application.yml如下:

server:
  port: 3344

spring:
  application:
    name:  cloud-config-center # 注冊進Eureka伺服器的微服務名
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/mp2333/springcloud-config.git # GitHub上面的git倉庫名字
          # 搜尋目錄
          search-paths:
            - springcloud-config
          # 注意:如果倉庫私有則需要添加username/password
      # 讀取分支
      label: master

# 服務注冊到eureka位址
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
           

編寫主啟動類,在主啟動類上添加注解

@EnableConfigServer

使3344微服務具有配置中心功能:

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

修改hosts檔案,增加映射,使本機模拟網址服務配置中心網址:

127.0.0.1 config-3344.com
           
2.3 GitHub倉庫建配置檔案

如圖,就是建立了一個簡單的配置檔案,用來測試能否通過配置中心微服務擷取内容。

七. SpringCloud服務配置
2.4 測試

配置讀取規則 (五種)

  • /{label}/{application}-{profile}.yml
# master分支
http://config-3344.com:3344/master/config-dev.yml
http://config-3344.com:3344/master/config-prod.yml
# dev分支
http://config-3344.com:3344/dev/config-dev.yml
http://config-3344.com:3344/dev/config-prod.yml
           
  • /{application}-{profile}.yml 預設master分支
http://config-3344.com:3344/config-dev.yml
http://config-3344.com:3344/config-prod.yml
           
  • /{application}/{profile}[/{label}]
# master分支
http://config-3344.com:3344/config/dev/master
http://config-3344.com:3344/config/prod/master
# dev分支
http://config-3344.com:3344/config/dev/dev
http://config-3344.com:3344/config/prod/dev
           

先啟動Eureka服務注冊中心,然後啟動服務配置中心微服務3344,通路 http://config-3344.com:3344/master/config-dev.yml ,我們可以看到3344微服務可以成功的讀取到遠端的配置檔案。

七. SpringCloud服務配置

是以現在,服務配置中心從遠端Git倉庫讀取配置檔案這一部分已經搭建完成:

七. SpringCloud服務配置

3. Config 用戶端配置與測試

3.1 建Moudle

建立Module:cloud-config-client-3355作為通路配置中心的用戶端

在其POM檔案中引入Config配置中心用戶端的啟動類:

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
           
3.2 編寫配置檔案bootstrap.yml

application.yml

是使用者級的資源配置項,而

bootstrap.yml

是系統級的資源配置項,

bootstrap.yml

的優先級更高,SpringCloud會建立一個"Bootstrap Context",作為Spring應用的“Application Context"的 父上下文。初始化的時候,“Bootstrap Context"負責從外部源加載配置屬性并解析配置,這兩個上下文共享一個從外部擷取的"Environment”。”Bootstrap“屬性有高優先級,預設情況系,它們不會被本地配置覆寫。"Bootstrap Context"和"Application Context"這兩個上下文有不同的約定,是以新增一個

bootstrap.yml

檔案,保證這兩個上下文的配置分離。

是以,要将Client子產品下的application.yml檔案改為bootstrap.yml,這是很關鍵的,因為bootstrap.yml是比application.yml先加載的。編寫bootstrap配置檔案如下:

server:
  port: 3355

spring:
  application:
    name: config-client
  cloud:
    # Config用戶端配置
    config:
      label: master # 分支名稱
      name: config # 配置檔案名稱
      profile: dev # 讀取字尾名稱   
      # 上述3個綜合:master分支上config-dev.yml的配置檔案被讀取
      uri: http://localhost:3344 # 配置中心位址
      # http://config-3344.com:3344/master/config-dev.yml

# 服務注冊到eureka位址
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
           

編寫3355服務的主啟動類,之後編寫其業務類:

@RestController
public class ConfigClientController {

    @Value("${server.info}") //配置中心config-dev.yml配置的内容
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo() {
        return configInfo;
    }
}
           
3.3 測試

下面測試用戶端是否能夠通過通路配置中心擷取配置資訊

按順序啟動Eureka服務注冊中心,Config服務配置中心後,啟動我們的服務配置中心用戶端3355進行測試:

七. SpringCloud服務配置
3.4 存在的問題

我們在GitHub上修改配置檔案内容,重新整理3344配置中心服務端,發現Config Server配置中心立刻響應并重新整理了配置資訊,但是!我們重新整理3355用戶端Config Client,發現沒有任何響應,配置資訊仍然是原來的配置資訊。

難道每次遠端修改了配置檔案後,用戶端都需要重新開機來進行對配置資訊的重新加載嗎?

4. Config 用戶端之動态重新整理

為了避免每次遠端更新配置資訊都需要重新開機用戶端微服務3355來加載更新的配置資訊,我們需要使用動态重新整理。

4.1 修改3355子產品

在POM中引入actuator監控:

其實actuator依賴幾乎處了是網關的微服務外都得加。
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
           
4.2 修改配置檔案

bootstrap.yml

中加入如下配置 暴露監控端點:

# 暴露監控端點
management:
  endpoints:
    web:
      exposure:
        include: "*"
           
4.3 @RefreshScope注解

在業務類Controller上添加

@RefreshScope

注解使用戶端服務具有重新整理功能:

@RestController
@RefreshScope
public class ConfigClientController {

    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo() {
        return configInfo;
    }

}
           
4.4 發送Post請求重新整理用戶端3355

該重新整理請求必須發送後,用戶端才能獲得重新整理後的資訊,重新整理用戶端的請求必須是POST請求:

curl -X POST "http://127.0.0.1:3355/actuator/refresh"
           

當出現以上資訊時激活重新整理用戶端3355成功,再次通路用戶端,發現已經可以得到重新整理後的配置資訊。

但是假設如果我們有多個微服務用戶端呢?難道每個微服務都需要執行一次POST請求進行手動重新整理嗎?事實上我們可以通過廣播的方式進行一次通知,處處生效,這裡就要知道消息總線 => SpringCloud Bus。

繼續閱讀