SpringCloud 之 Config 配置中心
本文較大篇幅引用https://www.mrhelloworld.com/config/,相關內容版權歸該文章作者所有
服務配置現狀
配置檔案是我們再熟悉不過的,在微服務系統中,每個微服務不僅僅只有程式碼,還需要連線其他資源,例如資料庫的配置或功能性的開關 MySQL、Redis 、Security 等相關的配置。
除了專案執行的基礎配置之外,還有一些配置是與我們業務有關係的,比如說七牛儲存、簡訊和郵件相關,或者一些業務上的開關。
但是隨著微服務系統的不斷迭代,整個微服務系統可能會成為一個網狀結構,這個時候就要考慮整個微服務系統的擴充套件性、伸縮性、耦合性等等。其中一個很重要的環節就是配置管理的問題。
常規配置管理解決方案缺點
- 硬編碼(需要修改程式碼、繁瑣、風險大)
- properties 或者 yml(叢集環境下需要替換和重啟)
- xml(重新打包和重啟)
為什麼使用 Spring Cloud Config
由於常規配置管理有很大的缺點,所以採用 Spring Cloud Config集中式的配置中心來管理每個服務的配置資訊。
Spring Cloud Config 在微服務分散式系統中,採用Server 服務端和Client 客戶端的方式來提供可擴充套件的配置服務。
服務端提供配置檔案的儲存,以介面的形式將配置檔案的內容提供出去;
客戶端通過介面獲取資料、並依據此資料初始化自己的應用。
配置中心負責管理所有服務的各種環境配置檔案。
配置中心預設採用Git
的方式儲存配置檔案,因此我們可以很容易的部署和修改,有助於環境配置進行版本管理。
Spring Cloud Config 解決了什麼問題
Spring Cloud Config 解決了微服務配置的中心化、版本控制、平臺獨立、語言獨立等問題。其特性如下:
- 提供服務端和客戶端支援(Spring Cloud Config Server 和 Spring Cloud Config Client)
- 集中式管理分散式環境下的應用部署
- 屬性值的加密和解密(對稱加密和非對稱加密)
- 基於 Spring 環境,無縫與 Spring 應用整合
- 可用於任何語言開發的程式
- 預設實現基於 Git ,可以進行版本管理
環境準備
config-demo
聚合工程。SpringBoot 2.2.4.RELEASE
、Spring Cloud Hoxton.SR1
。
eureka-server
:註冊中心(用於整合 Eureka 版的配置中心)eureka-server02
:註冊中心(用於整合 Eureka 版的配置中心)order-service
:訂單服務(用於整合 Eureka 版的配置中心)
倉庫
Repository name
:倉庫名稱Description(可選)
:倉庫描述介紹Public,Private
:倉庫許可權(公開共享,私有或指定合作者)Initialize this repository with a README
:新增一個 README.mdAdd .gitignore
:不需要進行版本管理的檔案型別,生成對應檔案.gitignore
Add a license
:證書型別,生成對應檔案LICENSE
配置檔案
不同環境的配置檔案,上傳至config-repo
倉庫
配置檔案的名稱不是亂起的,例如config-client-dev.yml
和config-client-prod.yml
這兩個檔案是同一個專案的不同環境,
專案名稱為config-client
, 一個對應開發環境,一個對應正式環境。test
表示測試環境
config-client.yml
server: port: 7777 # 埠 spring: application: name: config-client # 應用名稱 # 自定義配置 name: config-client-default
config-client-dev.yml
server: port: 7778 # 埠 spring: application: name: config-client # 應用名稱 # 自定義配置 name: config-client-dev
config-client-test.yml
server: port: 7779 # 埠 spring: application: name: config-client # 應用名稱 # 自定義配置 name: config-client-test
config-client-prod.yml
server: port: 7780 # 埠 spring: application: name: config-client # 應用名稱 # 自定義配置 name: config-client-prod
入門案例
入門案例講解:基礎版的配置中心(不整合 Eureka)
1.建立服務端
在config-demo
父工程下建立子專案config-server
。
2.新增依賴
<?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"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>config-server</artifactId> <version>1.0-SNAPSHOT</version> <!-- 繼承父依賴 --> <parent> <groupId>com.example</groupId> <artifactId>config-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <!-- 專案依賴 --> <dependencies> <!-- spring cloud config server 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <!-- spring boot test 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
3.配置檔案
server:
port: 8888 # 埠
spring:
application:
name: config-server # 應用名稱
cloud:
config:
server:
git:
uri: https://gitee.com/lusaisai2020/config-repo.git # 配置檔案所在倉庫地址
username: xxx # Github 等產品的登入賬號
password: xxx # Github 等產品的登入密碼
#default-label: master # 配置檔案分支
#search-paths: # 配置檔案所在根目錄
4.啟動類
啟動類新增@EnableConfigServer
註解。
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; // 配置中心服務端註解 @EnableConfigServer @SpringBootApplication public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
5.訪問規則
Spring Cloud Config 有一套訪問規則,我們通過這套規則在瀏覽器上直接訪問即可。
/{application}/{profile}[/{label}] /{application}-{profile}.yml /{label}/{application}-{profile}.yml /{application}-{profile}.properties /{label}/{application}-{profile}.properties
{application}
:應用名稱(目標服務名稱){profile}
:獲取指定環境配置,專案有開發環境、測試環境、生產環境,對應到配置檔案就是以 application-{profile}.yml 加以區分,例如 application-dev.yml、application-test.yml、application-prod.yml。預設值為 default。{label}
:表示 git 分支,預設是 master 分支,如果專案是以分支做區分也是可以的,那就可以通過不同的 label 來控制訪問不同的配置檔案。
6.測試
http://localhost:8888/config-client/default
http://localhost:8888/config-client/dev/master
http://localhost:8888/master/config-client-prod.yml
http://localhost:8888/config-client-test.yml
對於yml 和properties型別config可以完美轉換, 也就是說 你存的是yml 但是可以讀取為properties型別的反過來也是如此
http://localhost:8888/config-client-test.properties
訪問以上地址,如果可以正常返回資料,說明配置中心服務端一切正常。
建立客戶端
在config-demo
父工程下建立子專案config-client
。
新增依賴
<?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"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>config-client</artifactId> <version>1.0-SNAPSHOT</version> <!-- 繼承父依賴 --> <parent> <groupId>com.example</groupId> <artifactId>config-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <!-- 專案依賴 --> <dependencies> <!-- spring cloud starter config 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!-- spring boot web 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- spring boot test 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
配置檔案
客戶端配置檔名稱必須叫bootstrap.yml
解釋一下這個bootstrap.yml: spring cloud有一個“引導上下文"的概念,這是主應用程式的父上下文。
引導上下文負責從配置伺服器載入配置屬 性,以及解密外部配置檔案中的屬性。
和主應用程式載入application.(yml或 properties)中的屬性不同,引導上下 文載入(bootstrap.)中的屬性。配置在 bootstrap.*中的屬性有更高的優先順序
spring: cloud: config: name: config-client # 配置檔名稱,對應 git 倉庫中配置檔案前半部分 uri: http://localhost:8888 # config-server 服務端地址 label: master # git 分支 profile: dev # 指定環境
控制層
新增一個 RestController 用於測試獲取配置檔案資訊。
package com.example.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ConfigController { @Value("${name}") private String name; @GetMapping("/name") public String getName() { return name; } }
啟動類
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); } }
測試
訪問:http://localhost:7777/name 結果如下:
Spring Cloud Config 高可用
以上講了 Spring Cloud Config 最基礎的用法,如果我們的專案中使用了 Eureka 作為服務註冊發現中心,那麼 Spring Cloud Config 也應該註冊到 Eureka,方便其他服務使用,並且可以註冊多個配置中心服務端,實現高可用。
接下來就整合 Spring Cloud Config 到 Eureka。關於 Eureka 的相關知識大家可翻閱我的歷史文章進行學習。
新增配置檔案
在 Github 倉庫中增加配置檔案。
order-service-dev.yml
server: port: 9090 # 埠 spring: application: name: order-service # 應用名稱 # 配置 Eureka Server 註冊中心 eureka: instance: prefer-ip-address: true # 是否使用 ip 地址註冊 instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port client: service-url: # 設定服務註冊中心地址 defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/ # 自定義配置 name: order-service-dev
order-service-prod.yml
server: port: 9091 # 埠 spring: application: name: order-service # 應用名稱 # 配置 Eureka Server 註冊中心 eureka: instance: prefer-ip-address: true # 是否使用 ip 地址註冊 instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port client: service-url: # 設定服務註冊中心地址 defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/ # 自定義配置 name: order-service-prod
整合註冊中心
eureka-server
和eureka-server02
核心依賴部分一致,參照前文即可
Spring Cloud Config 服務端
服務端和基礎版的配置中心相比多了 Eureka 的配置,其他地方都是一樣的。
config-server
服務端構建完成以後再復刻一個config-server02
實現高可用。
依賴
config-server
和config-server02
核心依賴部分一致。注意是spring-cloud-config-server
依賴
<?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"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>config-server</artifactId> <version>1.0-SNAPSHOT</version> <!-- 繼承父依賴 --> <parent> <groupId>com.example</groupId> <artifactId>config-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <!-- 專案依賴 --> <dependencies> <!-- spring cloud config server 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <!-- netflix eureka client 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- spring boot test 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
配置檔案
config-server
的 application.yml
server:
port: 8888 # 埠
spring:
application:
name: config-server # 應用名稱
cloud:
config:
server:
git:
uri: https://github.com/imrhelloworld/config-repo # 配置檔案所在倉庫地址
#username: # Github 等產品的登入賬號
#password: # Github 等產品的登入密碼
#default-label: master # 配置檔案分支
#search-paths: # 配置檔案所在根目錄
# 配置 Eureka Server 註冊中心
eureka:
instance:
prefer-ip-address: true # 是否使用 ip 地址註冊
instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
client:
service-url: # 設定服務註冊中心地址
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
config-server02
的 application.yml
server:
port: 8889 # 埠
spring:
application:
name: config-server # 應用名稱
cloud:
config:
server:
git:
uri: https://github.com/imrhelloworld/config-repo # 配置檔案所在倉庫地址
#username: # Github 等產品的登入賬號
#password: # Github 等產品的登入密碼
#default-label: master # 配置檔案分支
#search-paths: # 配置檔案所在根目錄
# 配置 Eureka Server 註冊中心
eureka:
instance:
prefer-ip-address: true # 是否使用 ip 地址註冊
instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
client:
service-url: # 設定服務註冊中心地址
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
啟動類
config-server
和config-server02
啟動類核心程式碼一致。
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; // 開啟 EurekaClient 註解,當前版本如果配置了 Eureka 註冊中心,預設會開啟該註解 //@EnableEurekaClient // 配置中心服務端註解 @EnableConfigServer @SpringBootApplication public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class, args); } }
Spring Cloud Config 客戶端
客戶端加入 Eureka 以後,就不用直接和配置中心服務端打交道了,而是通過 Eureka 來訪問。
依賴
order-service
的 pom.xml。注意是spring-cloud-starter-config
依賴。
<?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"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>order-service</artifactId> <version>1.0-SNAPSHOT</version> <!-- 繼承父依賴 --> <parent> <groupId>com.example</groupId> <artifactId>config-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <!-- 專案依賴 --> <dependencies> <!-- spring boot web 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- netflix eureka client 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!-- spring cloud starter config 依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!-- spring boot test 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> </project>
配置檔案
order-service
的bootstrap.yml
,Eureka 註冊中心的配置在遠端 Git 倉庫的 order-service-dev.yml 中。
spring:
cloud:
config:
name: order-service # 配置檔名稱,對應 git 倉庫中配置檔案前半部分
label: master # git 分支
profile: dev # 指定環境
discovery:
enabled: true # 開啟
service-id: config-server # 指定配置中心服務端的 service-id
控制層
新增一個 RestController 用於測試獲取配置檔案資訊。
package com.example.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ConfigController { @Value("${name}") private String name; @GetMapping("/name") public String getName() { return name; } }
啟動類
package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; // 開啟 EurekaClient 註解,當前版本如果配置了 Eureka 註冊中心,預設會開啟該註解 //@EnableEurekaClient @SpringBootApplication public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }
測試
啟動註冊中心eureka-server
和eureka-server02
。
啟動配置中心服務端config-server
。
啟動配置中心客戶端order-service
。
當前環境在Eureka UI
介面中如下
訪問:http://localhost:9090/name 結果如下:
config 高可用還可以通過很多種方式, 比如說搭建一個nginx:
配置中心工作原理
開發人員將配置檔案儲存至 Git 遠端倉庫,或後期對 Git 遠端倉庫的檔案進行修改。
如果遠端倉庫發生了版本改變,Config Server 會將 Git 遠端倉庫中的檔案同步至本地倉庫中。
大家仔細觀察 Config Server 的控制檯可以看到類似如下資訊。
至此 Config 配置中心就講解結束了。