為什么要統(tǒng)一管理配置锚赤?
- 集中管理配置文件
- 不同環(huán)境不同配置
- 運(yùn)行期間動態(tài)調(diào)整配置
- 自動刷新
分布式配置中心
spring cloud config
是spring cloud
團(tuán)隊(duì)創(chuàng)建的一個(gè)全新項(xiàng)目仅胞,用來為分布式系統(tǒng)中的基礎(chǔ)設(shè)施和微服務(wù)應(yīng)用提供集中化的外部配置支持掸刊,它分為服務(wù)端和客戶端兩部分蔚龙,其中服務(wù)端也稱為分布式配置中心敷硅,它是一個(gè)獨(dú)立的微服務(wù)應(yīng)用松忍,用來連接配置倉庫并為客戶端提供獲取配置信息蹋绽,加密/解密信息等訪問接口,而客戶端則是微服務(wù)架構(gòu)中的各個(gè)微服務(wù)應(yīng)用或基礎(chǔ)設(shè)施逃魄,它們通過指定的配置中心管理應(yīng)用資源與業(yè)務(wù)相關(guān)的配置內(nèi)容荤西,并在啟動的時(shí)候從配置中心獲取和加載配置信息澜搅。spring cloud config
實(shí)現(xiàn)了對服務(wù)端和客戶端中環(huán)境變量和屬性設(shè)置的抽象映射伍俘,所以它除了適用于spring構(gòu)建的應(yīng)用程序之外,也可以在任何其他語言運(yùn)行的應(yīng)用程序中使用勉躺。由于spring cloud config
實(shí)現(xiàn)的配置中心默認(rèn)采用git來存儲配置信息癌瘾,所以使用spring cloud config
構(gòu)建的配置服務(wù)器,天然就支持對微服務(wù)應(yīng)用配置信息的版本管理饵溅,并且可以通過git
客戶端工具來方便地管理和訪問配置內(nèi)容妨退。當(dāng)然它也提供了對其他存儲方式的支持,比如說svn倉庫蜕企,本地化文件系統(tǒng)咬荷。
快速入門
構(gòu)建一個(gè)基于git存儲的分布式配置中心,并在客戶端中演示如何通過配置指定微服務(wù)應(yīng)用的所屬配置中心轻掩,并讓其能夠從配置中心獲取配置信息并綁定到代碼的整個(gè)過程幸乒。
構(gòu)建配置中心
創(chuàng)建一個(gè)名為config-server-git
的服務(wù)
第一步,加入依賴:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
我構(gòu)建的是父子依賴唇牧,關(guān)于spring cloud
的版本定義可以在父依賴中查看罕扎,相關(guān)代碼可以在博客最下方查看。
第二步丐重,創(chuàng)建springboot
程序主類腔召,加上注解@EnableConfigServer
,開啟spring cloud config
的服務(wù)端功能扮惦。
@EnableConfigServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
第三步臀蛛,在application.yml
中添加配置服務(wù)的基本信息以及git倉庫的相關(guān)信息
spring:
application:
name: config-server-git
cloud:
config:
server:
git:
uri: http://git.oschina.net/zhihaomiao/config-repo-demo
username: zhihao.miao
password: 13579qwertyu
search-paths: config-repo
server:
port: 9090
其中g(shù)it的配置分別表示如下內(nèi)容
-
spring.cloud.config.server.git.uri
: 配置的git倉庫位置 -
spring.cloud.config.server.git.search-paths
: 配置倉庫路徑下的相對搜索位置,可以配置多個(gè) -
spring.cloud.config.server.git.username
: 訪問git的用戶名 -
spring.cloud.config.server.git.password
: 訪問git倉庫的用戶密碼
配置規(guī)則詳解
在git配置信息中指定的倉庫位置崖蜜,http://git.oschina.net/zhihaomiao/config-repo-demo/config-repo
目錄下創(chuàng)建五個(gè)不同的配置文件
zhihao.yml
zhihao-dev.yml
zhihao-test.yml
zhihao-pro.yml
application.yml
內(nèi)容分別是:
zhihao.yml
from: git-default-1.0
spring:
datasource:
username: user_default
zhihao-dev.yml
from: git-dev-1.0
spring:
datasource:
username: user_dev
zhihao-test.yml
from: git-test-1.0
spring:
datasource:
username: user_test
zhihao-pro.yml
from: git-pro-1.0
spring:
datasource:
username: user_pro
application.yml
from: git-pro-1.0
spring:
datasource.
username:
zhihao.miao1
為了測試版本控制掺栅,在git
倉庫的master
分支中,我們?yōu)?code>from屬性加入1.0
的后綴纳猪,同時(shí)創(chuàng)建一個(gè)config-label-test
分支氧卧,并將各配置文件中的值用2.0
做為后綴.
完成上面的工作我們就可以通過url來訪問這些配置內(nèi)容了。
* /{application}/{profile}/[{label}]
* /{application}-{profile}.yml
* /{label}/{application}-{profile}.yml
* /{application}-{profile}.properties
* /{label}/{application}-{profile}.properties
上面的url會映射{application}-{profile}.yml
對應(yīng)的配置文件氏堤,其中{label}
對應(yīng)git上不同的分支沙绝,默認(rèn)是master
搏明。我們可以嘗試構(gòu)造不同的url來訪問不同的配置內(nèi)容,比如闪檬,要訪問config-label-test
分支星著,zhihao
應(yīng)用的prod環(huán)境,就可以訪問這個(gè)url:http://localhost:9090/zhihao/pro/config-label-test
{
name: "zhihao",
profiles: [
"pro"
],
label: "config-label-test",
version: "13c5f9da27b75ea85b1585803a39b00d8a9b75d4",
state: null,
propertySources: [
{
name: "http://git.oschina.net/zhihaomiao/config-repo-demo/config-repo/zhihao-pro.yml",
source: {
from: "git-pro-3.0",
spring.datasource.username: "user_pro3.0"
}
},
{
name: "http://git.oschina.net/zhihaomiao/config-repo-demo/config-repo/zhihao.yml",
source: {
from: "git-test-2.0",
spring.datasource.username: "user_default"
}
},
{
name: "http://git.oschina.net/zhihaomiao/config-repo-demo/config-repo/application.yml",
source: {
from: "git-pro-2.0",
spring.datasource.username: "zhihao.miao2"
}
}
]
}
我們看到j(luò)son中返回了應(yīng)用名是zhihao
粗悯,環(huán)境是prod
虚循,分支名是config-label-test
,以及default
環(huán)境和prod
環(huán)境的配置內(nèi)容,還包括applocation.yml的內(nèi)容样傍。另外之前提到的version
横缔,也可以觀察到,對應(yīng)于最后提交的git的commit_id
衫哥。
也可以輸入http://localhost:9090/abc/pro/config-label-test
茎刚,此時(shí)沒有abc.yml
文件,就會去application.yml
文件中查找,所以application.yml
可以匹配任何{application}
{
name: "abc",
profiles: [
"pro"
],
label: "config-label-test",
version: "13c5f9da27b75ea85b1585803a39b00d8a9b75d4",
state: null,
propertySources: [
{
name: "http://git.oschina.net/zhihaomiao/config-repo-demo/config-repo/application.yml",
source: {
from: "git-pro-2.0",
spring.datasource.username: "zhihao.miao2"
}
}
]
}
同時(shí)撤逢,我們可以看到config-server-git
的控制臺中還輸出了下面的內(nèi)容膛锭,配置服務(wù)器在從git中獲取了配置信息后,會存儲一份在config-server-git
的文件系統(tǒng)中蚊荣,實(shí)質(zhì)上config-server-git
是通過git clone
命令將配置內(nèi)容復(fù)制了一份在本地存儲初狰,然后讀取這些內(nèi)容并返回給微服務(wù)應(yīng)用進(jìn)行加載。
2017-08-15 22:10:07.568 INFO 28701 --- [io-9090-exec-10] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5ac2c286: startup date [Tue Aug 15 22:10:07 CST 2017]; root of context hierarchy
2017-08-15 22:10:07.579 INFO 28701 --- [io-9090-exec-10] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/var/folders/p0/kw_s_8xj2gqc929nys7cj2yh0000gn/T/config-repo-2847833657021753497/config-repo/application-pro.yml
2017-08-15 22:10:07.579 INFO 28701 --- [io-9090-exec-10] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/var/folders/p0/kw_s_8xj2gqc929nys7cj2yh0000gn/T/config-repo-2847833657021753497/config-repo/application.yml
2017-08-15 22:10:07.579 INFO 28701 --- [io-9090-exec-10] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5ac2c286: startup date [Tue Aug 15 22:10:07 CST 2017]; root of context hierarchy
config-server-git
通過從git在本地的倉庫暫存互例,可以有效的防止當(dāng)git倉庫出現(xiàn)故障而引起無法加載配置信息的情況奢入。我們可以通過斷開網(wǎng)絡(luò)(斷開wifi),再次發(fā)起從http://localhost:9090/zhihaomiao/pro/config-label-test
請求敲霍,在控制臺中可以輸出如下內(nèi)容俊马,這些內(nèi)容源于之前訪問時(shí)存在于config-server-git服務(wù)本地文件系統(tǒng)中的配置信息。
2017-08-15 22:23:15.002 WARN 28701 --- [nio-9090-exec-5] .c.s.e.MultipleJGitEnvironmentRepository : Could not fetch remote for config-label-test remote: http://git.oschina.net/zhihaomiao/config-repo-demo
2017-08-15 22:23:15.074 INFO 28701 --- [nio-9090-exec-5] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7060493e: startup date [Tue Aug 15 22:23:15 CST 2017]; root of context hierarchy
2017-08-15 22:23:15.088 INFO 28701 --- [nio-9090-exec-5] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/var/folders/p0/kw_s_8xj2gqc929nys7cj2yh0000gn/T/config-repo-2847833657021753497/config-repo/application-pro.yml
2017-08-15 22:23:15.089 INFO 28701 --- [nio-9090-exec-5] o.s.c.c.s.e.NativeEnvironmentRepository : Adding property source: file:/var/folders/p0/kw_s_8xj2gqc929nys7cj2yh0000gn/T/config-repo-2847833657021753497/config-repo/application.yml
2017-08-15 22:23:15.089 INFO 28701 --- [nio-9090-exec-5] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7060493e: startup date [Tue Aug 15 22:23:15 CST 2017]; root of context hierarchy
通過http訪問git server資源的格式:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
比如
http://localhost:9090/config-label-test/abc-pro.yml
等等肩杈。
客戶端配置映射
如何在微服務(wù)應(yīng)用中獲取上面的配置信息柴我?
- 創(chuàng)建一個(gè)應(yīng)用
config-client
,并在pom文件中引入依賴:
<dependencies>
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
- 創(chuàng)建springboot的應(yīng)用主類:
@SpringBootApplication
public class ConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigClientApplication.class,args);
}
}
- 創(chuàng)建
bootstrap.yml
配置扩然,來獲取配置文件的config-server-git
位置艘儒,如下:
spring:
application:
name: zhihaomiao
cloud:
config:
uri: http://localhost:9090/
profile: pro
label: config-label-test
server:
port: 8080
上述配置參數(shù)與git中存儲的配置文件中各個(gè)部分的對應(yīng)關(guān)系如下:
-
spring.application.name
: 對應(yīng)配置文件規(guī)則中的{application}
部分 -
spring.cloud.config.profile
:對應(yīng)配置文件規(guī)則中{profile}
部分 -
spring.cloud.config.label
:對應(yīng)配置文件規(guī)則中的{label}
部分 -
spring.cloud.config.uri
:配置中心config-server
的地址。
這里需要格外注意夫偶,上面的屬性必須配置在bootstrap.yml
中界睁,這樣config-server
中的配置信息才能被正確加載。springboot對配置文件的加載順序兵拢,對于本應(yīng)用jar包之外的配置文件加載會優(yōu)于應(yīng)用jar包內(nèi)的配置內(nèi)容翻斟,而通過bootstrap.yml
對config-server-git
的配置,使得該應(yīng)用會從config-server-git
中獲取一些外部配置信息说铃,這些信息的優(yōu)先級比本地的內(nèi)容要高访惜,從而實(shí)現(xiàn)了外部化配置嘹履。
springboot應(yīng)用配置文件加載的順序是bootstrap.yml-> config server中的配置 -> application.yml中的配置,這樣的順序進(jìn)行加載债热。
如果在application.yml中配置和遠(yuǎn)程配置相同的配置
application.yml
from: git-pro-1.0
spring:
datasource:
username: user_pro
那么application.yml中不會覆蓋當(dāng)前在config server中的配置砾嫉,并且讀取的還是遠(yuǎn)程倉庫的配置,那么如何進(jìn)行屬性覆蓋呢窒篱,可以看下面的博客焕刮。
@RestController
public class ConfigClientController {
private Logger log = LoggerFactory.getLogger(getClass());
@Value("${spring.datasource.username}")
private String username;
@Value("${from}")
private String from;
@GetMapping("/index")
public String index(){
log.info("username="+username+",form=="+from);
return "username="+username+",form=="+from;
}
}
訪問
http://localhost:8080/index
頁面顯示:
username=user_pro,form==git-pro-2.0
服務(wù)端詳解
- 遠(yuǎn)程git倉庫:用來存儲配置文件的地方,快速入門中應(yīng)用名為
zhihao
的多環(huán)境配置文件:zhihao-{profile}.properties
. - config server:這是我們快速入門中構(gòu)建的分布式配置中心墙杯,
config-server-git
項(xiàng)目配并,在該工程中指定了所要連接的git倉庫位置以及賬戶,密碼等連接信息霍转。 - 本地git倉庫:在
config server
的文件系統(tǒng)中荐绝,每次客戶端請求獲取配置信息時(shí)一汽,Config Server
從git倉庫中獲取最新的配置到本地避消,然后在本地git倉庫中讀取并返回。當(dāng)遠(yuǎn)程倉庫無法獲取時(shí)召夹,直接將本地的內(nèi)容返回岩喷。 - Service A,Service B:具體的微服務(wù)應(yīng)用监憎,他們指定了
config Server
地址纱意,從而實(shí)現(xiàn)從外部化獲取應(yīng)用自己要用的配置信息。這些應(yīng)用在啟動的時(shí)候鲸阔,會向config server
請求獲取配置信息來進(jìn)行加載偷霉。
客戶端應(yīng)用從配置管理中獲取配置信息遵從下面的執(zhí)行流程:
- 應(yīng)用啟動時(shí),根據(jù)
bootstrap.yml
中配置的應(yīng)用名{application}
,環(huán)境名{profile}
,分支名{label}
褐筛,向config server
請求獲取配置信息 -
config server
根據(jù)自己維護(hù)的git倉庫信息和客戶端傳遞過來的配置信息去查找配置信息类少。 - 根據(jù)
git clone
命令將找到的配置信息下載到Config Server
的文件系統(tǒng)中 -
Config Server
創(chuàng)建Spring的ApplictionContext實(shí)例,并從git本地倉庫中加載配置文件渔扎,最后將這些配置內(nèi)容讀取出來返回給客戶端應(yīng)用硫狞。 - 客戶端應(yīng)用在獲取外部配置文件后加載到客戶端的
ApplicationContext
實(shí)例,該配置內(nèi)容的優(yōu)先級高于客戶端jar包內(nèi)部的配置內(nèi)容晃痴,所以在jar包中重復(fù)的內(nèi)容不再被加載残吩。
Config Server
巧妙的通過git clone
將配置信息存于本地,起到了緩存的作用倘核,即使當(dāng)git服務(wù)端無法訪問的時(shí)候泣侮,依然可以取Config Server
中緩存內(nèi)容進(jìn)行試驗(yàn)。
參考文檔:
官網(wǎng)The Bootstrap Application Context
官網(wǎng)Quick Start
官網(wǎng)Client Side Usage