1. 程式人生 > 實用技巧 >09.SpringCloud Config (分散式配置中心)

09.SpringCloud Config (分散式配置中心)

1.概述

分散式系統面臨的配置問題
是什麼

能幹嘛
  • 集中管理配置檔案
  • 不同環境不同配置,動態化的配置更新,分環境部署比如dev/test/prod/beta/release
  • 執行期間動態調整配置,不再需要在每個服務部署的機器上編寫配置檔案,服務會向配置中心統一拉取配置自己的資訊
  • 當配置發生變動時,服務不需要重啟即可感知到配置的變化並應用新的配置
  • 將配置資訊以REST介面的形式暴露 post、curl訪問重新整理均可....

與Github整合配置由於SpringCloud Config預設使用Git來儲存配置檔案(也有其它方式,比如支援svn和本地檔案,但最推薦的還是Git,而且使用的是http/https訪問的形式)
官網
https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.2.1.RELEASE/reference/html/

2.Config服務端配置與測試

Config服務端的建立

用你自己的賬號在Github上新建一個名為sprincloud-config的新Repository新增三個配置檔案進這個倉庫config-dev.yml
config: 
   info: dev1
config-prod.yml
config: 
   info: prod1
config-test.yml
config: 
   info: test1

新建Module模組cloud-config-center-3344它為Cloud的配置中心模組CloudConfig Centerpom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud2020</artifactId>
        <groupId>com.chl.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-config-center-3344</artifactId>

    <dependencies>
        <!--springcloud 的服務端依賴-->
        <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>
        <dependency>
            <groupId>com.chl.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
yml
server:
  port: 3344
spring:
  application:
    name: cloud-config-center
  cloud:
    config:                                    #分支/config-環境名.yml
      server:   #http://config-3344.com:3344/master/config-dev.yml
        git:    #githud倉庫的位置  用碼雲不行,識別不了,只能githud
          uri:  https://github.com/badbad001/springcloud-config.git
          search-paths:
            - springcloud-config #倉庫名稱
      label: master  #倉庫的分支

eureka:
  client:
    service-url:
      defaultZone:  http://localhost:7001/eureka
啟動類
@SpringBootApplication
@EnableConfigServer //開啟服務配置中心
public class ConfigCenterMain3344 {
    public static void main(String[] args) {
            SpringApplication.run(ConfigCenterMain3344 .class,args);
        }
}
windows下修改hosts檔案,增加對映
127.0.0.1 config-3344.com
測試通過Config微服務是否可以從Github上獲取配置內容啟動微服務3344http://config-3344.com:3344/master/config-dev.yml

配置讀取規則

/{label}/{application}-{profile}.yml(最推薦使用這種方式)

master分支dev分支

/{application}-{profile}.yml


/{application}-{profile}[/{label}]



重要配置細節總結
成功實現了用SpringCloud Config 通過GitHub獲取配置資訊

3.Config客戶端配置與測試

新建cloud-config-client-3355pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud2020</artifactId>
        <groupId>com.chl.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-config-client-3355</artifactId>

    <dependencies>
        <!--config 客戶端的依賴-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>com.chl.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


</project>

bootstap.yml


配置如下
#這個檔名 bootrap.yml 系統級別的 優先於 application.yml(使用者界別)
server:
  port: 3355

spring:
  application:
    name: config-client
  cloud: #config客戶端的配置
    config: #組裝成就是 http://localhost:3344/master/config-dev.yml 配置的是從哪裡獲取配置資訊
      uri: http://localhost:3344   #配置中心地址
      label: master   #分支名稱 
      name: config    #配置檔名稱
      profile: dev    #讀取字尾名稱
     
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka

修改config-dev.yml配置並提交到GitHub中,比如加個變數age或者版本號version主啟動
@SpringBootApplication
public class ConfigClientMain3355 {
    public static void main(String[] args) {
            SpringApplication.run( ConfigClientMain3355.class,args);
        }
}
業務類
@RestController
public class ConfigClientController {

    //獲取統一配置的資料資訊
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo(){
        return configInfo;
    }
}
測試啟動Config配置中心3344微服務並自測啟動3355作為Client準備訪問
成功實現了客戶端3355訪問SpringCloud Config3344通過GitHub獲取配置資訊

問題隨時而來,分散式配置的動態重新整理問題
  • Linux運維修改GitHub上的配置檔案內容做調整
  • 重新整理3344,發現ConfigServer配置中心立刻響應
  • 重新整理3355,發現ConfigServer客戶端沒有任何響應
  • 3355沒有變化除非自己重啟或者重新載入
  • 難道每次運維修改配置檔案,客戶端都需要重啟??噩夢

4.Config客戶端之動態重新整理

避免每次更新配置都要重啟客戶端微服務3355

動態重新整理步驟

修改3355模組pom引入actuator監控
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
yml
#這個檔名 bootrap.yml 系統級別的 優先於 application.yml(使用者界別)
server:
  port: 3355

spring:
  application:
    name: config-client
  cloud: #config客戶端的配置
    config: #組裝成就是 http://localhost:3344/master/config-dev.yml 配置的是從哪裡獲取配置資訊
      uri: http://localhost:3344   #配置中心地址
      label: master   #分支名稱 
      name: config    #配置檔名稱
      profile: dev    #讀取字尾名稱
     
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
#暴露監控埠,用於重新整理分散式的配置
management:
  endpoints:
    web:
      exposure:
        include: "*"
@RefreshScope業務類Controller修改
@RestController
@RefreshScope //用於重新整理分散式的配置
//可能需要服務中心先請求一次,而且還要運維人員發起一個請求去重新整理相應的客戶端
//例如運維人員改了,還要重新整理客戶端3355 curl -X POST "http://localhost:3355/actuator/refresh
public class ConfigClientController {

    //獲取統一配置的資料資訊
    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo(){
        return configInfo;
    }
}
此時修改github---> 3344 ---> 3355http://localhost:3355/configInfo 3355改變了沒有???沒有改變,(┬_┬)
為什麼需要運維人員傳送Post請求重新整理3355 必須是Post請求
curl -X POST "http://localhost:3355/actuator/refresh"
再次訪問http://localhost:3355/configInfo成功實現了客戶端3355重新整理到最新配置內容 避免了服務的重啟

還存在的問題

假如有多個微服務客戶端3355/3366/3377。。。。每個微服務都要執行一次post請求,手動重新整理?可否廣播,一次通知,處處生效?我們想大範圍的自動重新整理,求方法 就要用到 SpringCloud Bus 訊息匯流排