前言
SpringBoot與SpringCloud版本對應(yīng)關(guān)系:https://start.spring.io/actuator/info
SpringCloud與Spring-Cloud-Alibaba版本對應(yīng)關(guān)系:
Spring Cloud Alibaba官方版本聲明:https://github.com/alibaba/spring-cloud-alibaba/wiki。
spring官網(wǎng)也能看到springboot與springcloud版本對應(yīng)關(guān)系:https://spring.io/projects/spring-cloud-alibaba#learn
微服務(wù)中配置文件的問題
1、配置文件相對分散饰迹。在一個微服務(wù)架構(gòu)下再扭,配置文件會隨著微服務(wù)的增多變的越來越多,而且分散在各個微服務(wù)中,不好統(tǒng)一配置和管理。
2、配置文件無法區(qū)分環(huán)境日缨。微服務(wù)項目會有多個環(huán)境。例如:開發(fā)環(huán)境掖看、測試環(huán)境匣距、預(yù)發(fā)布環(huán)境、生產(chǎn)環(huán)境哎壳。每一個環(huán)境所使用的配置一般情況下是不同的毅待。打個比方,出個包更新到預(yù)發(fā)布環(huán)境归榕,還得把配置改好了才能進(jìn)行尸红,很痛苦。
3、配置文件無法動態(tài)實時更新外里。我們修改了配置文件之后怎爵,必須重新啟動微服務(wù)才能使配置生效,這對一個正在運(yùn)行的項目來說是非常不友好的盅蝗。
基于上述這些問題鳖链,我們就需要配置中心的加入來解決問題。
配置中心的思路是:
- 1墩莫、首先把項目中各種配置全部都放到一個集中的地方進(jìn)行統(tǒng)一管理芙委,并提供一套標(biāo)準(zhǔn)的接口。
- 2狂秦、微服務(wù)來配置中心拉取自己的配置题山。
- 3、當(dāng)配置中心里面的參數(shù)有更新時故痊,也能通知到各個微服務(wù)實時的過來同步最新的信息,使之動態(tài)更新玖姑。
業(yè)界常見配置中心
- Apollo
- Disconf
- Spring Cloud Config
- Nacos Config
Nacos Config與Spring Boot整合
引入maven依賴
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
三愕秫、在微服務(wù)中添加nacos config的配置
注意:不能使用原來的application.yml作為配置文件,而是新建一個bootstrap.yml作為配置文件
配置文件優(yōu)先級(由高到低):
bootstrap.properties > bootstrap.yml > application.properties > application.yml
spring:
application:
name: service-product
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 # Nacos配置中心的地址
file-extension: yaml # 配置的格式
profiles:
active: dev # 環(huán)境標(biāo)識
四焰络、在nacos中添加配置
五戴甩、配置動態(tài)刷新
上述操作已經(jīng)實現(xiàn)了配置的遠(yuǎn)程存放和拉取。但是如果此時修改了配置闪彼,我們的程序是無法讀取到的甜孤。因此,我們需要開啟配置的動態(tài)刷新功能畏腕。
為了方便測試缴川,在nacos中的service-product-dev.yaml配置項中添加以下配置,用于后續(xù)打印輸出描馅。
config:
appName: jack-product
gender: man
方式一:硬編碼方式(此方式默認(rèn)就支持動態(tài)刷新把夸,但是不夠簡潔,不推薦)
@RestController
@RequestMapping("/nacos/config")
public class NacosConfigController {
@Autowired
private ConfigurableApplicationContext configurableApplicationContext;
@RequestMapping("/test1")
public String test1() {
return this.configurableApplicationContext.getEnvironment().getProperty("config.appName");
}
}
方式二:注解方式(推薦)
@RestController
@RequestMapping("/nacos/config")
@RefreshScope // 注解方式讀取配置铭污,如果需要動態(tài)更新恋日,需要加上此注解
public class NacosConfigController {
@Value("${config.gender}")
private String gender;
@RequestMapping("/test2")
public String test2() {
return gender;
}
}
六、配置共享
當(dāng)配置越來越多的時候嘹狞,就發(fā)現(xiàn)有很多配置是重復(fù)的岂膳,這時候就需要考慮能不能將公共配置提取出來,然后實現(xiàn)共享呢磅网?當(dāng)然是可以的谈截。接下來演示如何實現(xiàn)這一功能。
6.1 同一個微服務(wù)的不同環(huán)境之間共享配置
如果想在同一個微服務(wù)的不同環(huán)境之間實現(xiàn)配置共享,其實很簡單傻盟。
只需要提取一個以spring.application.name命名的配置文件速蕊,然后將所有環(huán)境的公共配置放在里面即可。
-
第一步:新建一個名為service-product.yaml配置娘赴,用于存放商品微服務(wù)的公共配置
-
第二步:新建一個名為service-product-test.yaml的配置规哲,用于存放測試環(huán)境的配置
-
第三步:修改service-product-dev.yaml的配置,存放開發(fā)環(huán)境獨(dú)有的配置
第四步:進(jìn)行測試
@RestController
@RequestMapping("/nacos/config")
@RefreshScope // 注解方式讀取配置诽表,如果需要動態(tài)更新唉锌,需要加上此注解
public class NacosConfigController {
@Value("${config.gender}")
private String gender;
@RequestMapping("/test2")
public String test2() {
return gender;
}
}
啟動微服務(wù),訪問測試
接下來竿奏,修改bootstrap.yml中的配置袄简,將active修改為test,再次訪問測試泛啸,觀察輸出結(jié)果
6.2 不同微服務(wù)之間共享配置
不同微服務(wù)之間共享配置的原理绿语,類似于文件引入,就是定義一個公共配置候址,然后在當(dāng)前配置中引入吕粹。
-
1、在nacos中定義一個DataId為all-service.yaml的配置岗仑,用于所有微服務(wù)共享
2匹耕、修改微服務(wù)的bootstrap.yml
shared-configs配置方式
spring:
application:
name: service-product
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 # Nacos配置中心的地址
file-extension: yaml # 配置的格式
#新版本配置方式 可以配置多個
shared-configs[0]:
data_id: all-service.yaml # 要引入的配置
group: DEFAULT_GROUP # 可以不寫,默認(rèn)值為DEFAULT_GROUP
refresh: true # 默認(rèn)是false,如果需要支持自動刷新需要配置true,搭配@RefreshScope實現(xiàn)動態(tài)刷新
#老版本配置方式
#shared-dataids: all-service.yaml # 要引入的配置
#refreshable-dataids: all-service.yaml # 動態(tài)刷新時也刷新引入的配置
profiles:
active: test # 環(huán)境標(biāo)識
extension-configs配置方式
spring:
application:
name: service-product
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848 # Nacos配置中心的地址
file-extension: yaml # 配置的格式
#新版本配置方式 可以配置多個
extension-configs[0]:
data_id: service.yaml # 要引入的配置
group: DEFAULT_GROUP # 可以不寫荠雕,默認(rèn)值為DEFAULT_GROUP
refresh: true # 默認(rèn)是false,如果需要支持自動刷新需要配置true,搭配@RefreshScope實現(xiàn)動態(tài)刷新
extension-configs[1]:
data_id: rocketmq.yaml # 要引入的配置
group: DEFAULT_GROUP # 可以不寫稳其,默認(rèn)值為DEFAULT_GROUP
refresh: true # 默認(rèn)是false,如果需要支持自動刷新需要配置true,搭配@RefreshScope實現(xiàn)動態(tài)刷新
profiles:
active: test # 環(huán)境標(biāo)識
- 3、添加測試方法
@RestController
@RequestMapping("/nacos/config")
@RefreshScope // 注解方式讀取配置炸卑,如果需要動態(tài)更新既鞠,需要加上此注解
public class NacosConfigController {
@Value("${test.name}")
private String name;
@RequestMapping("/test3")
public String test3() {
return name;
}
}
7、Nacos Config動態(tài)刷新原理
動態(tài)監(jiān)聽
- Push表示服務(wù)端主動將數(shù)據(jù)變更信息推送給客戶端
- Pull表示客戶端主動去服務(wù)端拉取數(shù)據(jù)
Nacos 采用的是 Pull 模式矾兜,但并不是簡單的 Pull损趋,而是一種長輪訓(xùn)機(jī)制,它結(jié)合 Push 和 Pull 兩者的優(yōu)勢(nacos并沒有push)椅寺』氩郏客戶端采用長輪訓(xùn)的方式定時發(fā)起 Pull 請求,去檢查服務(wù)端配置信息是否發(fā)生了變更返帕,如果發(fā)生了變更桐玻,則客戶端會根據(jù)變更的數(shù)據(jù)獲得最新的配置。所謂的長輪訓(xùn)荆萤,是客戶端發(fā)起輪訓(xùn)請求之后镊靴,服務(wù)端如果有配置發(fā)生變更铣卡,就直接返回。
如果客戶端發(fā)起 Pull 請求后偏竟,發(fā)現(xiàn)服務(wù)端的配置和客戶端的配置是保持一致的煮落,那么服務(wù)端會先 “Hold” 住這個請求,也就是服務(wù)端拿到這個連接之后在指定的時間段內(nèi)一直不返回結(jié)果踊谋,直到這段時間內(nèi)配置發(fā)生變化蝉仇,服務(wù)端會把原來 “Hold” 住的請求進(jìn)行返回。Nacos 服務(wù)端收到請求之后殖蚕,先檢查配置是否發(fā)生了變更轿衔,如果沒有,則設(shè)置一個定時任務(wù)睦疫,延期 29.5s 執(zhí)行害驹,并且把當(dāng)前的客戶端長輪訓(xùn)加入 allSubs 隊列。這個時候有兩種方式觸發(fā)該鏈接結(jié)果的返回:// 后面單獨(dú)看config server的源碼解析
1蛤育、第一種是在等待 29.5s 后觸發(fā)自動檢查機(jī)制宛官,這個時候不管配置有沒有發(fā)生變化,都會把結(jié)果返回客戶端瓦糕。而 29.5s 就是這個長連接保持的時間摘刑。
2、第二種是在 29.5s 內(nèi)任意一個時刻刻坊,通過 Nacos Dashboard 或者 API 的方式對配置進(jìn)行了修改,就會觸發(fā)一個事件機(jī)制党晋,監(jiān)聽該事件的任務(wù)會遍歷 allSubs 隊列谭胚,找到發(fā)生變更的配置項對應(yīng)的 ClientLongPolling 任務(wù),將變更的數(shù)據(jù)通過該任務(wù)的連接進(jìn)行返回未玻,就完成一次 “推送” 操作灾而。
這樣既能夠保證客戶端實時感知配置的變化,也降低了服務(wù)端的壓力扳剿。其中旁趟,這個長連接的會話超時時間默認(rèn)是 30s。
nacos config 動態(tài)刷新流程圖
參考:
https://blog.csdn.net/qq_31155349/article/details/108818208