(十四)、SpringCloud Config分散式配置中心
分散式配置中心介紹
分散式系統面臨的配置問題
微服務意味著要將單體應用中的業務拆分成一個個子服務,每個服務的粒度相對較小,因此係統中會出現大量的服務。由於每個服務都需要必要的配置資訊才能執行,所以一套集中式的、動態的配置管理設施是必不可少的。
SpringCloud提供了ConfigServer來解決這個問題,我們每一個微服務自己帶著一個application.yml,上百個配置檔案的管理.……
是什麼
SpringCloud Config為微服務架構中的微服務提供集中化的外部配置支援,配置伺服器為各個不同微服務應用的所有環境提供了一箇中心化的外部配置。
怎麼玩
SpringCloud Config分為服務端
- 服務端也稱為分散式配置中心,它是一個獨立的微服務應用,用來連線配置伺服器併為客戶端提供獲取配置資訊,加密/解密資訊等訪問介面。
- 客戶端則是通過指定的配置中心來管理應用資源,以及與業務相關的配置內容,並在啟動的時候從配置中心獲取和載入配置資訊配置伺服器預設採用git來儲存配置資訊,這樣就有助於對環境配置進行版本管理,並且可以通過git客戶端工具來方便的管理和訪問配置內容。
能幹嘛
- 集中管理配置檔案
- 不同環境不同配置,動態化的配置更新,分環境部署比如dev/test/prod/beta/release
- 執行期間動態調整配置,不再需要在每個服務部署的機器上編寫配置檔案,服務會向配置中心統一拉取配置自己的資訊
- 當配置發生變動時,服務不需要重啟即可感知到配置的變化並應用新的配置
- 將配置資訊以REST介面的形式暴露 - post/crul訪問重新整理即可…
與GitHub整合配置
由於SpringCloud Config預設使用Git來儲存配置檔案(也有其它方式,比如支援SVN和本地檔案),但最推薦的還是Git,而且使用的是http/https訪問的形式
官網
https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.2.1.RELEASE/reference/html/
Config配置總控中心搭建
自己建立一個github倉庫,然後克隆到本地,在本地新增三個檔案,提交到遠端倉庫,倉庫設定公有遠端訪問不需要賬號密碼
例如:Clrs/SpringCloud Config (gitee.com)
-
config-dev.yml
config: info: "master branch,springcloud-config/config-dev.yml version=7"
-
config-prod.yml
config: info: "master branch,springcloud-config/config-prod.yml version=1"
-
config-test.yml
config:
info: "master branch,springcloud-config/config-test.yml version=1"
新建Module模組cloud-config-center-3344,它即為Cloud的配置中心模組CloudConfig Center
POM
<?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>cloud2021</artifactId>
<groupId>com.ylc.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-config-center-3344</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--新增訊息匯流排RabbitMQ支援-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<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>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 #註冊進Eureka伺服器的微服務名
cloud:
config:
server:
git:
uri: https://gitee.com/yanglingcong/spring-cloud-config #GitHub上面的git倉庫名字
####搜尋目錄
search-paths:
- springcloud-config
####讀取分支
label: master
#服務註冊到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
url需要用https連線方式
主啟動類
package com.ylc.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@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上獲取配置內容
-
啟動ConfigCenterMain3344
-
頁面返回結果
配置讀取規則
-
/{label}/{application}-{profile}.yml(推薦)
-
master分支
http://config-3344.com:3344/master/config-dev.yml
http://config-3344.com:3344/master/config-test.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-test.yml
http://config-3344.com:3344/dev/config-prod.yml
-
-
/{application}-{profile}.yml
http://config-3344.com:3344/config-dev.yml
http://config-3344.com:3344/config-test.yml
http://config-3344.com:3344/config-prod.yml
http://config-3344.com:3344/config-xxxx.yml(不存在的配置)
預設訪問配置檔案的master分支
- /{application}/{profile}[/{label}]
http://config-3344.com:3344/config/dev/master
http://config-3344.com:3344/config/test/master
http://config-3344.com:3344/config/test/dev
- 重要配置細節總結
- /{name}-{profiles}.yml
- /{label}-{name}-{profiles}.yml
- label:分支(branch)
- name:服務名
- profiles:環境(dev/test/prod)
成功實現了用SpringCloud Config通過GitHub獲取配置資訊
Config客戶端配置與測試
客戶端訪問服務端
新建cloud-config-client-3355
POM
<?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>cloud2021</artifactId>
<groupId>com.ylc.cloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-config-client-3355</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!--新增訊息匯流排RabbitMQ支援-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<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>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>
bootstrap.yml
applicaiton.yml是使用者級的資源配置項
bootstrap.yml是系統級的,優先順序更加高
Spring Cloud會建立一個Bootstrap Context,作為Spring應用的Application Context的父上下文。
初始化的時候,BootstrapContext負責從外部源載入配置屬性並解析配置。這兩個上下文共享一個從外部獲取的Environment。
Bootstrap屬性有高優先順序,預設情況下,它們不會被本地配置覆蓋。Bootstrap context和Application Context有著不同的約定,所以新增了一個bootstrap.yml檔案,保證Bootstrap Context和Application Context配置的分離。
要將Client模組下的application.yml檔案改為bootstrap.yml,這是很關鍵的,因為bootstrap.yml是比application.yml先載入的。bootstrap.yml優先順序高於application.yml。
YML
server:
port: 3355
spring:
application:
name: config-client
cloud:
#Config客戶端配置
config:
label: master #分支名稱
name: config #配置檔名稱
profile: dev #讀取字尾名稱 上述3個綜合:master分支上config-dev.yml的配置檔案被讀取http://config-3344.com:3344/master/config-dev.yml
uri: http://localhost:3344 #配置中心地址k
#服務註冊到eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
修改config-dev.yml配置並提交到GitHub中,比如加個變數age或者版本號version
主啟動
package com.ylc.cloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@SpringBootApplication
public class ConfigClientMain3355
{
public static void main(String[] args) {
SpringApplication.run(ConfigClientMain3355.class, args);
}
}
業務類
package com.ylc.cloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope
public class ConfigClientController
{
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo()
{
return configInfo;
}
}
測試
-
啟動Config配置中心3344微服務並自測
http://config-3344.com:3344/master/config-prod.yml
http://config-3344.com:3344/master/config-dev.yml -
啟動3355作為Client準備訪問配置檔案裡面的節點資訊
http://localhost:3355/configlnfo
成功實現了客戶端3355訪問SpringCloud Config3344通過GitHub獲取配置資訊可題隨時而來
分散式配置的動態重新整理問題
- Linux運維修改GitHub上的配置檔案內容做調整
- 重新整理3344,發現ConfigServer配置中心立刻響應
- 重新整理3355,發現ConfigClient客戶端沒有任何響應、
- 3355沒有變化除非自己重啟或者重新載入
- 難到每次運維修改配置檔案,客戶端都需要重啟??噩夢
Config動態重新整理之手動版
避免每次更新配置都要重啟客戶端微服務3355
動態重新整理步驟:
修改3355模組
POM引入actuator監控
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
修改YML,新增暴露監控埠配置:
# 暴露監控端點
management:
endpoints:
web:
exposure:
include: "*"
@RefreshScope業務類Controller修改增加@RefreshScope
註解
測試
此時修改github配置檔案內容 -> 訪問3344 -> 訪問3355
http://localhost:3355/configInfo
需要運維人員傳送Post請求重新整理3355
curl -X POST "http://localhost:3355/actuator/refresh"
再次測試成功