分布式系統(tǒng)面臨的問(wèn)題
微服務(wù)意味著要將單體應(yīng)用中的業(yè)務(wù)拆分成一個(gè)個(gè)子服務(wù) ,每個(gè)服務(wù)的粒度相對(duì)較小屡拨,因此系統(tǒng)中會(huì)出現(xiàn)大量的服務(wù)只酥。由于每個(gè)服務(wù)都需要必要的配置信息才能運(yùn)行,比如每個(gè)微服務(wù)都需要?個(gè)配置?件,并且,如果有?個(gè)微服務(wù)都需要連接數(shù)據(jù)庫(kù)那么就需要配4次數(shù)據(jù)庫(kù)相關(guān)配置,并且當(dāng)數(shù)據(jù)庫(kù)發(fā)?改動(dòng),那么需要同時(shí)修改4個(gè)微服務(wù)的配置?件才可以洁仗,所以一套集中式的层皱、動(dòng)態(tài)的配置管理設(shè)施是必不可少的。
關(guān)于config
SpringCloud Config為微服務(wù)架構(gòu)中的微服務(wù)提供集中化的外部配置支持配置服務(wù)器為各個(gè)不同微服務(wù)應(yīng)用的所有環(huán)境提供了一個(gè)中心化的外部配置赠潦。
springcloud config可以做到:
- 1叫胖、不同環(huán)境不同配置,動(dòng)態(tài)化的配置更新她奥,分環(huán)境部署比如dev/test/prod/beta/release
- 2瓮增、運(yùn)行期間動(dòng)態(tài)調(diào)整配置,不再需要在每個(gè)服務(wù)部署的機(jī)器上編寫(xiě)配置文件哩俭,服務(wù)會(huì)向配置中心統(tǒng)一拉取配置自己的信息
- 3绷跑、當(dāng)配置發(fā)生變動(dòng)時(shí),服務(wù)不需要重啟即可感知到配置的變化并應(yīng)用新的配置
- 4凡资、將配置信息以REST接口的形式暴露
更多介紹查看 官網(wǎng)
使用config
由于SpringCloud Config默認(rèn)使用Git來(lái)存儲(chǔ)配置文件(也有其它方式砸捏,比如支持svn和本地文件,但最推薦的還是Git隙赁,而且使用的是http/https訪問(wèn)的形式)垦藏,這里我們使用的是git的方式來(lái)存放配置文件。
搭建配置服務(wù)中心
前提環(huán)境
-
git倉(cāng)庫(kù)
? 首先我們需要建立一個(gè)新的配置文件的存放倉(cāng)庫(kù)伞访,github或者gitee均可掂骏。
? 我已經(jīng)準(zhǔn)備好了一個(gè)倉(cāng)庫(kù),倉(cāng)庫(kù)地址是:https://github.com/martaintao/spring-config-center-demo.git,倉(cāng)庫(kù)的master分支中有
config-dev.yml
、config-test.yml
厚掷、config-prod.yml
三個(gè)配置文件弟灼。 -
注冊(cè)中心
需要準(zhǔn)備好一個(gè)注冊(cè)中心,我這里使用的是Eureka冒黑。
依賴
<!--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-web</artifactId>
</dependency>
<!--監(jiān)控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
改yml
server:
port: 7070
spring:
application:
name: cloud-config-server
cloud:
config:
server:
git:
uri: https://github.com/martaintao/spring-config-center-demo.git # 因?yàn)槭莗ublic的倉(cāng)庫(kù)田绑,所以不需要認(rèn)證。
label: master # 指定分支
# 注冊(cè)中心
eureka:
client:
#表示是否將自己注冊(cè)進(jìn)EurekaServer默認(rèn)為true
register-with-eureka: true
#是否從EurekaServer抓取已有的注冊(cè)消息抡爹,默認(rèn)為true辛馆,單節(jié)點(diǎn)無(wú)所謂,集群必須設(shè)置為true才能配合ribbon使用負(fù)載均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:8080/eureka/
配置啟動(dòng)類
@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer // 啟動(dòng)配置服務(wù)中心
public class ConfigCenterApplication7070 {
public static void main(String[] args) {
SpringApplication.run(ConfigCenterApplication7070.class,args);
}
}
讀取配置文件
springcloud提供給了我們http的方式去獲取遠(yuǎn)程的配置文件信息。請(qǐng)求的api拼接有如下5種規(guī)則:
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
label
表示分支昙篙,application
一般是配置文件中的spring.config.name
屬性腊状,profile
就是環(huán)境標(biāo)識(shí),比如dev/test/prod
如上述項(xiàng)目配置完成啟動(dòng)了之后苔可,我們可以訪問(wèn)http://localhost:7070/master/config-dev.yml
(使用的是上面第三種規(guī)則的格式)就可以訪問(wèn)到config-dev.yml
的內(nèi)容缴挖。當(dāng)我們改動(dòng)文件的時(shí)候,刷新請(qǐng)求也會(huì)實(shí)時(shí)更新焚辅。
config客戶端
配置依賴
<!-- spring config -->
<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>
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
建立yml
注意映屋,這里是創(chuàng)建
bootstrap.yml
,這個(gè)配置?件的作?是,先到配置中?加載配置,然后加載到application.yml
中。
application.yml
是用戶級(jí)的資源配置項(xiàng)同蜻。
bootstrap.yml
是系統(tǒng)級(jí)的棚点,優(yōu)先級(jí)比application.yml
更高。
server:
port: 7001
spring:
application:
name: cloud-eureka-consumer-useradmin
cloud:
config:
label: master # 分支名稱
name: config # 配置文件名稱 列如config-dev.yml 名稱就是config
profile: dev # 環(huán)境(讀取后綴)
uri: http://127.0.0.1:7070 # 配置中心地址
eureka:
client:
#表示是否將自己注冊(cè)進(jìn)EurekaServer默認(rèn)為true
register-with-eureka: true
#是否從EurekaServer抓取已有的注冊(cè)消息湾蔓,默認(rèn)為true
fetch-registry: true
service-url:
defaultZone: http://localhost:8080/eureka/
編寫(xiě)測(cè)試接口
@RestController
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/getConfigInfo")
public String getConfigInfo(){
return configInfo;
}
}
啟動(dòng)類
@EnableEurekaClient
@SpringBootApplication
public class ConfigClientApplication7001 {
public static void main(String[] args) {
SpringApplication.run(ConfigClientApplication7001.class,args);
}
}
服務(wù)啟動(dòng)之后瘫析,訪問(wèn)http://localhost:7001/getConfigInfo
,如果返回了config-dev.yml
中config.info的內(nèi)容的話默责,便表示配置成功了贬循。
但是發(fā)現(xiàn)客戶端啟動(dòng)之后,如果配置文件更新了桃序,客戶端不重啟的話杖虾,新的配置是不會(huì)生效的,所以我們需要配置能夠動(dòng)態(tài)刷新媒熊。
動(dòng)態(tài)刷新
要實(shí)現(xiàn)動(dòng)態(tài)刷新需要在客戶端添加
spring-boot-starter-actuator
依賴奇适。
客戶端添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
修改配置文件boostrap.yml
# 暴露監(jiān)控端點(diǎn)
management:
endpoints:
web:
exposure:
include: "*"
修改controller
在controller上添加
@RefreshScope
注解即可
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/getConfigInfo")
public String getConfigInfo(){
return configInfo;
}
}
重啟服務(wù)
到這里還不能自動(dòng)動(dòng)態(tài)刷新,當(dāng)我們的配置文件更新了芦鳍,我們只需要向客戶端發(fā)送/actuator/refresh
的post
請(qǐng)求(比如向上面的客戶端發(fā)起post
請(qǐng)求:https://localhost:7001/actuator/refresh
)即可無(wú)需重啟可獲取最新的配置文件嚷往。
問(wèn)題
如果有許多客戶端該怎么辦?用腳本確實(shí)可以實(shí)現(xiàn)批量更新怜校,但是這種方式顯然不夠優(yōu)雅间影,可否廣播一次注竿,然后所以的客戶端都可以自動(dòng)刷新呢茄茁?當(dāng)然可以,不過(guò)這里就需要用到springcloud的bus消息總線的知識(shí)了巩割,這里因?yàn)槲疫€沒(méi)有學(xué)到bus總線裙顽,所以暫時(shí)就給出示例了,有興趣可以自己去實(shí)現(xiàn)下宣谈。