Spring Cloud Config是Spring創(chuàng)建的一個全新的服務端/客戶端項目节榜,為應用提供分布式的配置存儲脑慧,提供集中化的外部配置支持什猖。它除了適用于Spring構建的應用程序外野宜,也可以在其他語言運行的應用程序中使用乔妈。
Spring Cloud Config分為服務端和客戶端兩部分辞嗡。其中服務端稱為分布式配置中心捆等,用來連接配置倉庫并為客戶端提供獲取配置信息欲间、加密/解密信息的功能楚里;客戶端則是微服務架構中的各個微服務應用,它們通過指定的配置中心來管理與業(yè)務相關的配置內容猎贴,并在啟動的時候從配置中心獲取和加載配置信息班缎。
Spring Cloud Config實現(xiàn)的配置中心默認采用Git來存儲配置信息,但也提供了對其他存儲方式的支持她渴,比如SVN倉庫达址、本地文件系統(tǒng)。在本例中構建了一個基于Git存儲的分布式配置中心趁耗,并在客戶端中演示了如何制定應用所屬的配置中心沉唠,并能夠從配置中心獲取配置信息的整個過程。
1苛败、準備Git服務器
在Windows系統(tǒng)下搭建本地的Git服務器满葛,可參看教程 http://blog.csdn.net/qwer971211/article/details/71156055
創(chuàng)建一個新的版本庫
在此版本庫里創(chuàng)建config-repo目錄,提交兩個配置文件
config-client-development.properties
config-client-production.properties
user.role=Developer
user.password=pass
user.role=User
user.password=pass
2罢屈、服務端(配置中心)
項目依賴
創(chuàng)建一個Maven工程嘀韧,引入spring-cloud-config-server模塊依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
服務端應用實現(xiàn)
一個SpringBoot應用通過自動配置注釋@EnableConfigServer引入所有必需的設置。
@SpringBootApplication
@EnableConfigServer
public class ConfigServer {
public static void main(String[] args) {
SpringApplication.run(ConfigServer.class, args);
}
}
服務端配置
配置Git倉庫信息和Basic-Authentication的用戶名和密碼
spring.application.name=config-server
server.port=8888
#配置Git倉庫位置
spring.cloud.config.server.git.uri=ssh://admin@localhost:29418/Test.git
#配置倉庫路徑下的相對搜索位置缠捌,可以配置多個
spring.cloud.config.server.git.searchPaths=config-repo
#配置為true表示啟動時就克隆配置緩存到本地锄贷。
spring.cloud.config.server.git.clone-on-start=true
#訪問Git倉庫的用戶名
spring.cloud.config.server.git.username=admin
#訪問Git倉庫的用戶密碼
spring.cloud.config.server.git.password=admin
#Basic-Authentication
security.user.name=root
security.user.password=s3cr3t
服務端運行
訪問URL規(guī)則如下,其中{label}占位符為引用Git分支曼月,{application}為引用客戶端的應用程序名稱谊却,{profile}為引用客戶端當前活動的應用程序配置文件。
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
啟動工程哑芹,訪問 http://localhost:8888/config-client/development/master
得到配置信息炎辨,證明服務端已配置正確。
{
"name": "config-client",
"profiles": [
"development"
],
"label": "master",
"version": "45bc95dec293023587669efb86cef8be61d1c1d7",
"state": null,
"propertySources": [
{
"name": "ssh://admin@localhost:29418/Test.git/config-repo/config-client-development.properties",
"source": {
"user.password": "pass",
"user.role": "Developer"
}
}
]
}
客戶端(微服務應用)
項目依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
客戶端應用實現(xiàn)
@SpringBootApplication
@RestController
public class ConfigClient {
@Value("${user.role}")
private String role;
@Value("${user.password}")
private String password;
public static void main(String[] args) {
SpringApplication.run(ConfigClient.class, args);
}
@RequestMapping(value = "/whoami/{username}", method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE)
public String whoami(@PathVariable("username") String username) {
return String.format("Hello %s! You are a(n) %s and your password is '%s'.\n", username, role, password);
}
}
客戶端配置
在bootstrap.properties文件中配置
spring.application.name=config-client
server.port=8000
spring.cloud.config.uri=http://localhost:8888
spring.cloud.config.profile=development
spring.cloud.config.label=master
spring.cloud.config.username=root
spring.cloud.config.password=s3cr3t
spring.cloud.config.fail-fast=true
客戶端運行
http://localhost:8000/whoami/Peter
返回 Hello Peter! You are a(n) Developer and your password is 'pass'.
配置項加密/解密
在使用Spring Cloud Config的加密解密功能時绩衷,有一個必要的前提需要我們注意蹦魔。為了啟動該功能激率,我們需要在配置中心的運行環(huán)境中安裝不限長度的JCE版本(Unlimited Strength Java Cryptography Extension)。雖然勿决,JCE功能在JRE中自帶乒躺,但是默認使用的是有長度限制的版本。我們可以從Oracle的官方網(wǎng)站下載到它低缩,它是一個壓縮包嘉冒,解壓后可以看到下面三個文件:
- README.txt
- Local_policy.jar
- US_export_policy.jar
我們需要將local_policy.jar和US_export_policy.jar兩個文件復制$JAVA_HOME/jre/lib/security目錄下,覆蓋原來的默認內容咆繁。到這里讳推,加密解密的準備工作就完成了。
對稱加密
通過encrypt.key屬性在配置文件bootstrap.properties中直接指定密鑰信息(對稱性密鑰)玩般。
encrypt.key=symmetricKey
通過POST 使用/encrypt對請求的body內容進行加密银觅,得到密文
$ curl localhost:8888/encrypt -d mysecret
保存到配置文件提交到Git倉庫
user.role=Developer
user.password={cipher}4e9908d0197d510a2250e5cca64991f525b56cc0ec0983d23c87531ba8d9959c
調用http://localhost:8000/whoami/Peter 可看到我們的配置值被正確解密
Hello Peter! You are a(n) Developer and your password is 'mysecret'.
非對稱加密
首先使用Java keytool生成一個新的密鑰庫,包括一個RSA密鑰對
$> keytool -genkeypair -alias config-server-key \
-keyalg RSA -keysize 4096 -sigalg SHA512withRSA \
-dname 'CN=Config Server,OU=Spring Cloud,O=Baeldung' \
-keypass my-k34-s3cr3t -keystore config-server.jks \
-storepass my-s70r3-s3cr3t
之后坏为,我們將創(chuàng)建的密鑰庫添加到我們的服務器的bootstrap.properties中并重新運行它
#非對稱密鑰
encrypt.key-store.location=classpath:/config-server.jks
encrypt.key-store.password=my-s70r3-s3cr3t
encrypt.key-store.alias=config-server-key
encrypt.key-store.secret=my-k34-s3cr3t
同理通過POST 使用/encrypt對請求的body內容進行加密究驴,得到密文
$ curl localhost:8888/encrypt -d mysecret
保存到配置文件提交到Git倉庫
user.role=Developer
user.password={cipher}AgAN74/iWyGPPzFNSKNJTuTvqgLlKZA0OW2EkBTdSuJKrZ4QAx3czXctQHJCY5SHO17wymGFLRtHZa23Hw8TPovHnymEW+WC6qus/aVWt4WFR+QK3LTNu9/+jZv+2rZff0eHGRcwWus43BIvyFdP/LjnO0M68WcIE26KZmlO2WnLCmAaw3rtdG1M4kJnCQrneG9cVR2xg/fjM4QyTAOM/oV8xNani5yH1oDza5JIaDmJMzkjtvo04vZ6PxdhuRlPDjygJ/CxTyjHd+bZqDBPfSH1IkOSv6tMg2G5o54Bch1nFqxMvPLi9sF5WaKpJRqLlPkua/Jz4Jat3NgsQ+fSgWdNZX0ukC+TT067wOffACZdYAd6mwBUvk97QKQCBR4htInTD7KKu84D8iHQHw41TS5sJds98AESvFtSc7+2jI8i0V1eEsM56ohoATC9KYpOuS0d3zydkrB3n3VNVFijbeHQjoYpQqZIXvuFSCwp0Aj1xPR/R7zdvOMS0t0uH4xavk0a194RQ2XRpAZN+g5+wdmQsqTH4OVgUWK/Jqr3nMWbGevlKDQ3e8gXV3S362feWoB78Y3ZHLxeM9ZSaZn2yqKewbzqbnrWDE7MtYjmslZdDM+qQ/jN2+IBHcIpQcWzwZiWYpPp/vJZ9xqy3DoNIzH5UrP8L9xDhpOggfxxgnLw1+PHqO88yKJfbulWpt6A5CwmRC+TBXLbbWsWc06JdlCh
調用http://localhost:8000/whoami/Peter 可看到我們的配置值被正確解密
Hello Peter! You are a(n) Developer and your password is 'mysecret'.
總結
現(xiàn)在我們已經(jīng)可以創(chuàng)建一個配置服務器來提供從Git存儲庫到客戶端應用程序的一組操作的實現(xiàn)。我們也可以將Config Server作為一個普通的微服務應用匀伏,納入到Eureka的服務治理體系中洒忧。對于服務端的負載均衡配置和客戶端的配置中心指定都通過服務治理機制一并解決,即實現(xiàn)了高可用够颠,也可實現(xiàn)自我維護熙侍。