SpringCloudConfig是SpringCloud創建的用來爲分佈式系統中的基礎設施和微服務應用提供集中化的外部配置支持,它分爲客戶端和服務端兩部分。服務端也稱爲分佈式配置中心,是一個獨立的微服務應用,用來連接配置倉庫併爲客戶端提供獲取配置信息,加密/解密信息等訪問接口。而客戶端則是微服務架構中各微服務應用或基礎設施,通過指定的配置中心來管理應用資源與業務相關的配置內容,並在啓動的時候從配置中心獲取和加載配置信息。
使用
構建配置中心
新建一個SpringBoot項目,命名config-server;添加一下依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
在主類上使用@EnableConfigServer
註解來開啓配置中心服務端功能。
@SpringBootApplication
@EnableConfigServer
public class ConfigserverApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigserverApplication.class, args);
}
}
在application.properties文件中添加git倉庫配置:
spring.application.name=config-server
server.port=9000
#表示配置中心所在倉庫的位置
spring.cloud.config.server.git.uri=https://github.com/wqh8522/spring-cloud-config.git
#倉庫路徑下的的相對搜索位置,可以配置多個
spring.cloud.config.server.git.search-paths=config-client
#git的用戶名
spring.cloud.config.server.git.username=username
#git的密碼
spring.cloud.config.server.git.password=password
然後啓動項目,如果成功啓動,繼續下面步驟。
倉庫配置
根據上面git配置信息指定的倉庫位置創建一個config-client目錄作爲配置倉庫,並新建一下4個文件:
- wqh.properties: form=wqh_default_1.0
- wqh-dev.properties:form=wqh_dev_1.0
- wqh-prod.properties:form=wqh_prod_1.0
- wqh-test.properties:form=wqh_test_1.0
因爲使用的是git做配置倉庫,所以SpringCloudConfig天然就支持對微服務應用配置信息的版本管理,所以在git倉庫中添加一個分支,將上面的1.0改爲2.0,以測試版本控制。這裏對於git的操作省略。
接下來可以通過瀏覽器、postman、curl等工具直接訪問配置內容。配置信息的url和配置文件的映射關係如下:
- /{application}/{profile}[/{label}]
- /{application}-{profile}.yml
或/{application}-{profile}.properties
- /{label}/{application}-{profile}.yml
或/{label}/{application}-{profile}.properties
這裏的url會映射{application}-{profile}.yml
對應的配置文件。{label}對應git上不同的分支,默認是master。
訪問url:http://localhost:9000/wqh/test/config-label
,該url的是要訪問config-label分支,wqh應用的test環境。
可以看到該json返回了應用名wqh,環境名test,分支名config-label,以及test環境和默認環境配置的內容。配置服務器在從git中獲取到配置信息後,實際上會存儲一份在config-server的文件系統,也就是複製一份在本地存儲。
客戶端配置
同樣新建一個SpringBoot項目,命名config-client,映入依賴:
<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>
創建bootstrap.properties文件來獲取配置文件的config-server位置。屬性配置必須在bootstrap.properties文件中才正確加載config-server中的配置信息。
#配置服務名
spring.application.name=wqh
#服務id
server.port=60000
#配置對應文件規則中的{profile}部分
spring.cloud.config.profile=test
#配置對應文件規則中的{label}
spring.cloud.config.label=config-label
#配置中心的地址
spring.cloud.config.uri=http://localhost:9000/
創建一個接口來獲取配置中心的name屬性:
@RestController
@RefreshScope
public class HelloController {
@Value("${form}")
private String form;
@Autowired
private Environment environment;
@GetMapping("/get_name")
public String name(){
return "form:"+form;
}
@GetMapping("/get_name_env")
public String name_env(){
return environment.getProperty("form","undefine");
}
}
訪問接口即可獲取指定的信息。
配置介紹
架構
客戶端從配置管理中獲取配置流程:
- 應用啓動,根據bootstrap.properties中配置的應用名{application}、環境名{profile}、分支名{label},行配置中心獲取配置信息。
- ConfigServer根據自己維護的Git倉庫信息和客戶端傳遞過來的配置定位信息去查找配置信息。
- 通過git clone命令將找到的配置信息下載到ConfigServer的文件系統中。
- ConfigServer創建Spring的ApplicationContext實例,並從git本地倉庫中加載配置文件,最後將這些配置文件內容讀取出來返回給客戶端
- 客戶端應用在獲得外部配置文件後加載到客戶端ApplicationContext實例,該配置內容的優先級高於客戶端Jar包內部的配置內容,所以在Jar包中重複的內容將不再被加載。
服務端配置
- URL佔位符配置
前面用到了三種佔位符:
- {application}:映射到客戶端的spring.application.name
- {profile}:映射到客戶端的spring.profiles.active或者是application-{profile}.yml
- {label}:映射到版本庫的分支
- {application}:映射到客戶端的spring.application.name
這些佔位符除了用於表示配置文件的規則外,還可以用於ConfigServer中對git倉庫的URI配置。如:
spring.cloud.config.server.git.uri=https://github.com/wqh8522/spring-cloud-config/{application}
使用{label}佔位符需要注意,如果git倉庫分支和標籤包含“/”,那麼{label}參數在HTTP的URL中應該使用“(_)”來替代。
客戶端配置
- 失敗快速響應
在客戶端的bootstrap.properties文件中添加配置即可:
spring.cloud.config.fail-fast=true
- 重試機制
客戶端需要使用spring-retry和spring-boot-starter-aop依賴:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
重試機制的配置:
# 配置重試次數,默認爲6
spring.cloud.config.retry.max-attempts=6
# 間隔乘數,默認1.1
spring.cloud.config.retry.multiplier=1.1
# 初始重試間隔時間,默認1000ms
spring.cloud.config.retry.initial-interval=1000
# 最大間隔時間,默認2000ms
spring.cloud.config.retry.max-interval=2000
- 動態刷新
添加spring-boot-starter-actuator
依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
重啓客戶端,查看控制檯可以看有/refresh接口,通過post請求發送到該接口就能刷新配置。
加密解密
在jdk自帶了限制長度的JCE,所以從Oracle官網下載不限制長度版本:點擊下載jce8,解壓之後得到三個文件
將上面兩個jar包複製到
- 對稱加密
對稱加密簡單,只需要設置密鑰即可,但是這個密鑰必須配置在bootstrap.properties中,否則無法獲取到密鑰信息。如下:
encrypt.key=wqh3520
訪問/encrypt/status
接口:
加密相關接口:
1. /encrypt/status:查看加密狀態;
2. /key:查看密鑰端點;
3. /encrpt:對請求的body內容進行加密的端點;
4. /decrypt:對請求的body內容解密的端點。
接着使用postman等工具來加密解密數據:
這裏加密數據之後,拿到加密後的字符在配置文件中使用需要以{cipher}開頭,如:
form={cipher}0fa7c3c11e5625fe3d90f03ac8820aaaa90336a4245b5d90cea61547ef94b8f7
- 非對稱加密
對稱只要配置一個密鑰即可,而非對稱加密是密鑰對,所以安全性比對稱加密要搞。生成密鑰對可以使用jdk自帶的keytool工具,使用命令:
keytool -genkeypair -alias config-server -keyalg RSA -keystore config-server.keystore
然後再命令執行的文件夾下會生成一個名爲:config-server.keystore
的文件,將其拷貝到配置中心的src\main\resources
目錄下。然後在配置文件中添加加密配置:
encrypt.key-store.location=config-server.keystore
encrypt.key-store.alias=config-server
#在命令行第一次輸入的密鑰庫口令
encrypt.key-store.password=123456
#最後輸入的口令
encrypt.key-store.secret=654321
後面的操作與對稱加密一樣。
配置高可用配置中心
改造config-server
在微服務架構中,基本每一個服務都會配置成高可用的,配置中心也一樣。對上面的config-server進行改造,添加eureka的依賴,是其作爲服務在服務註冊中心註冊。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
在主類上使用@EnableEurekaClient
或@EnableDiscoveryClient
開啓服務發現功能,使其成爲eureka的一個客戶端。然後添加eureka的相關配置:
eureka.client.service-url.defaultZone=http://localhost:8888/eureka
改造config-client
與前面一樣需要添加依賴,使用註解開啓功能和配註冊中心。另外還需要修改spring.cloud.config.*
的配置,最終配置如下:
#配置服務名
spring.application.name=wqh
#服務id
server.port=60000
eureka.client.service-url.defaultZone=http://localhost:8888/eureka
#開啓通過服務來訪問config-server
spring.cloud.config.discovery.enabled=true
#指定配置中心註冊的服務名
spring.cloud.config.discovery.service-id=config-server
spring.cloud.config.profile=dev
參考:《SpringCloud微服務實戰》