Spring Boot應(yīng)用最大的特點(diǎn)就是使用配置來(lái)代替編碼剂买,很多時(shí)候啟用某一個(gè)功能只需要引入相關(guān)的starter贱呐,再加入對(duì)應(yīng)的配置項(xiàng)就可以了弃秆,例如數(shù)據(jù)源届惋,安全性,中間件等等菠赚。對(duì)于單個(gè)項(xiàng)目脑豹,我們一般會(huì)把配置項(xiàng)放到application.property或者application.yaml中,在不同的環(huán)境中替換相應(yīng)的配置值就可以了衡查。但在Spring Cloud項(xiàng)目中瘩欺,因?yàn)橐胛⒎?wù)概念,導(dǎo)致整個(gè)系統(tǒng)的服務(wù)實(shí)例會(huì)大大增加拌牲,這樣如果系統(tǒng)新增了一個(gè)配置項(xiàng)俱饿,還像以前那樣逐個(gè)去手工替換配置文件,運(yùn)維人員估計(jì)要累到吐血塌忽。而且傳統(tǒng)的方式還有一個(gè)問(wèn)題拍埠,替換配置文件以后必須要重啟整個(gè)服務(wù),這對(duì)于部分應(yīng)用來(lái)說(shuō)也是不可接受的土居。
我們之前在介紹Consul的時(shí)候枣购,提到了Consul除了提供服務(wù)的注冊(cè)/發(fā)現(xiàn)功能以外嬉探,還提供了key/value的存儲(chǔ)功能,而且Consul可以提供對(duì)存儲(chǔ)鍵值對(duì)的CP(強(qiáng)一致性棉圈,類(lèi)似于zookeeper)保證涩堤,這樣我們就可以利用Consul來(lái)實(shí)現(xiàn)統(tǒng)一配置中心的相關(guān)功能了(Spring Cloud Config 組件也提供基于GIT或SVN的配置中心解決方案)。Spring Cloud 已經(jīng)為Consul配置中心提供相關(guān)的實(shí)現(xiàn)框架 — spring-cloud-starter-consul-config分瘾。我們只需要在每個(gè)服務(wù)模塊中加入相關(guān)的依賴(lài):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
然后在resources目錄中新增一個(gè)配置文件bootstrap.yml定躏,用于配置遠(yuǎn)程配置中心的相關(guān)信息:
spring:
cloud:
consul:
host: 192.168.1.220
port: 8500
discovery:
prefer-ip-address: true
config:
enabled: true
prefix: config
default-context: application
profile-separator: ','
data-key: data
format: yaml
這個(gè)bootstrap.yml是spring boot的引導(dǎo)配置文件,其加載優(yōu)先級(jí)高于其它任何配置芹敌,是在一個(gè)獨(dú)立的父級(jí)上下文(Bootstrap Context)中加載解析的。與配置中心相關(guān)的配置都應(yīng)該放到該配置文件之中垮抗,才能夠?qū)崿F(xiàn)初始化應(yīng)用程序之前先到配置中心去抓取必要的配置氏捞。spring.cloud.consul.config的相關(guān)配置項(xiàng)意義如下:
- enabled: 是否啟用consul配置中心
- prefix: 配置項(xiàng)在consul中的根目錄,默認(rèn)是config
- default-context: 所有服務(wù)的公共配置所在的配置目錄冒版,默認(rèn)是application
- profile-separator: 配置項(xiàng)目錄中profile名稱(chēng)的分隔符液茎,默認(rèn)是 “,”
- data-key:配置項(xiàng)的key名稱(chēng),默認(rèn)是data
- format:配置項(xiàng)的值的文件格式
比如按照以上的配置辞嗡,如果spring.application.name設(shè)置為order-service捆等,spring.profiles.active為dev的服務(wù)啟動(dòng)后默認(rèn)會(huì)去consul的key/value目錄的以下四個(gè)位置去查找配置信息,配置的key為data续室,值必須為yaml格式:
- config/application,dev/:公共配置信息栋烤,profile為dev
- config/application/:公共配置信息
- config/order-service,dev/:order-service服務(wù)的專(zhuān)屬配置信息,profile為dev
- config/order-service/:order-service服務(wù)的專(zhuān)屬配置信息
現(xiàn)在我們?cè)趏rder-service服務(wù)上測(cè)試一下挺狰,首先在consul的config/application/和config/order-service/目錄分別加入兩個(gè)配置項(xiàng):
然后添加一個(gè)測(cè)試的ConfigController 明郭,測(cè)試配置項(xiàng)的注入:
@RestController
@RequestMapping("/api/config")
@Slf4j
public class ConfigController {
@Value("${global-config.key1}")
private String key1;
@Value("${service-config.key2}")
private String key2;
@GetMapping("/test-config-center")
public void testConfigCenter() {
log.info("global-config.key1:{},service-config.key2:{}", key1, key2);
}
}
訪問(wèn) http://localhost:9001/api/config/test-config-center 就可以看到控制臺(tái)輸出了對(duì)應(yīng)的配置值:
2020-04-27 11:18:19.505 INFO 15828 --- [nio-9001-exec-9] c.g.d.s.o.controller.Controller : global-config.key1:value1,service-config.key2:value2
我們?cè)賮?lái)測(cè)試一下配置項(xiàng)的動(dòng)態(tài)更新。為了支持動(dòng)態(tài)更新配置參數(shù)丰泊,我們需要在注入?yún)?shù)的Spring Component上加入一個(gè)@RefreshScope注解薯定,這樣才能在參數(shù)更新后刷新當(dāng)前的scope:
@RestController
@RequestMapping("/api/config")
@Slf4j
@RefreshScope
public class ConfigController
然后在consul ui中修改配置項(xiàng)的值,將global-config.key1的值修改為:modified-value瞳购,保存后再次訪問(wèn)http://localhost:9001/api/config/test-config-center话侄,可以看到控制臺(tái)打印出的屬性值已經(jīng)是我們修改后的最新的結(jié)果了:
2020-04-27 11:45:01.978 INFO 16368 --- [TaskScheduler-1] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-config/order-service/'}, BootstrapPropertySource {name='bootstrapProperties-config/application/'}]
LOGBACK: No context given for c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@2107186835
2020-04-27 11:45:01.992 INFO 16368 --- [TaskScheduler-1] o.s.boot.SpringApplication : No active profile set, falling back to default profiles: default
2020-04-27 11:45:02.009 INFO 16368 --- [TaskScheduler-1] o.s.boot.SpringApplication : Started application in 0.694 seconds (JVM running for 70.244)
2020-04-27 11:45:02.150 INFO 16368 --- [TaskScheduler-1] o.s.c.e.event.RefreshEventListener : Refresh keys changed: [global-config.key1]
2020-04-27 11:45:14.614 INFO 16368 --- [io-9001-exec-10] c.g.d.s.o.controller.ConfigController : global-config.key1:modified-value,service-config.key2:value2
其實(shí)配置項(xiàng)的動(dòng)態(tài)刷新是通過(guò)不斷的輪詢(xún)Consul的HTTP API,檢測(cè)相關(guān)的配置目錄是否發(fā)生了變化來(lái)實(shí)現(xiàn)的学赛,輪詢(xún)的間隔時(shí)間可以通過(guò)spring.cloud.consul.config.watch.delay來(lái)配置年堆,默認(rèn)是1000毫秒,如果不想啟用自動(dòng)刷新機(jī)制罢屈,可以配置spring.cloud.consul.config.watch.enabled=false
本文的相關(guān)代碼可以查看這里 spring-cloud-demo