序言
Spring Cloud Bus将輕量級消息代理程式連結到分布式系統的節點。然後可以将其用于廣播狀态更改(例如配置更改)或其他管理指令。目前唯一的實作是使用AMQP代理作為傳輸,但是其他傳輸的路線圖上仍具有相同的基本功能集(還有一些取決于傳輸)。
此文章僅限入門 SpringCloud版本為 Greenwich
就是說在使用了一些分布式配置中心後(這裡以Spring Cloud Config為例),這配置的重新整理,一般我們都會重新開機,但是我們使用了Spring Cloud Bus後啊,就可以做到這些配置的熱更新。
窺探
假設我們現在已經有一個項目使用了Spring Cloud Config 并且使用git 作為配置檔案的管理處啊。那麼我們可以在項目的依賴中加入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
并且這個項目yml加入
management:
endpoint:
health:
show-details: always
endpoints:
web:
exposure:
include: '*'
這裡啊我友善測試 我設定了
include: '*'
按道理可以,隻引入
-refresh
就行了。
然後這裡我們controller 裡加入一個注解
@RefreshScope
@RestController
@RefreshScope
public class OrderController {
@Value("${fulinlin.name}")
String fulinlin;
@GetMapping("/getConfig")
public String getConfig() {
return fulinlin;
}
}
然後呢我們在git中 更新這個
fulinlin.name
這個屬性後,我們用指令調用一下
/actuator/refresh
接口
curl -X POST http://localhost:7001/actuator/refresh
然後呢在控制台中會列印一串日志,這個串日志呢就是,在從配置中心啊重新擷取配置。然後我們在通路
http://localhost:7001/getConfig
可以發現這個配置啊已經重新整理了。
使用
如果我們這個項目做了個叢集,難道我們要一個一個的去調用這個接口,做重新整理嗎?有沒有一種簡單的方式呢?對就是bus。大概是這樣的,我們引用這個bus啊 結合mq官方有 rabbitmq kafka的實作,
然後每個引用bus的服務 都連接配接這個mq,啟動的時候給mq中建立一個隊列,然後這些隊列都會有同一個訂閱者
然後在我們的服務中專門有一個監聽,來監聽這個建立隊列,然後隻要有一個服務送出了重新整理請求,這些服務呢都會受到重新整理的請求,這樣所有服務都重新整理了。
在依賴中加入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
這裡就使用rabbitmq了 kafka 其實使用起來跟這個沒啥差別的。
然後呢controller保持不變
@RestController
@RefreshScope
public class OrderController {
@Value("${fulinlin.name}")
String fulinlin;
@GetMapping("/getConfig")
public String getConfig() {
return fulinlin;
}
}
這裡可以使用
-Dserver.port
多起幾台服務友善測試。啟動後我們在rabbimq的背景檢視一下是否有隊列進行建立
可以看到有一個
springCloudBus
的一個交換器 是一個topic的類型,這裡你可以了解為是一個釋出訂閱模式。
我們在git上事先先修改下
fulinlin.name
這個屬性。
然後在指令中發送
curl -X POST http://localhost:7001/actuator/bus-refresh
注意啊這裡是
bus-refresh
然後呢你看控制台,列印了一串有關重新拉取的日志。
然後你在重新整理下請求看下,是不是這個
fulinlin.name
這個屬性 已經更新了。
注意
本地配置中心
如果是使用的是本地配置中心。那麼你的配置中心需要重新開機一下,切記啊,因為本地配置中心在啟動的時候讀取的檔案是不會因為修改而重新讀取的!!!
重新整理範圍
我們希望可以重新整理微服務中某個具體執行個體的配置
Spring Cloud Bus對這種場景也有很好的支援:
/actuator/bus-refresh
接口還提供了
destination
參數,用來定位具體要重新整理的應用程式。比如,我們可以請求
/actuator/bus-refresh?destination=customers:9000
,此時總線上的各應用執行個體會根據
destination
屬性的值來判斷是否為自己的執行個體名,若符合才進行配置重新整理,若不符合就忽略該消息。
destination
參數除了可以定位具體的執行個體之外,還可以用來定位具體的服務。定位服務的原理是通過使用
Spring
的
PathMatecher
(路徑比對)來實作,比如:
/actuator/bus-refresh?destination=customers:**
(以冒号的路徑分隔符:)來确定一個執行個體是否處理該消息,該配置的請求會觸發
customers
服務的所有執行個體進行重新整理。
優化
這裡是使用任意的一個服務端口來重新整理配置了,其實你把這個工作交給配置中心也是沒問題的。在配置中心中加入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
請求配置中心的
/actuator/bus-refresh
就可以做到配置的重新整理了。
這裡始終要調取url,我們可以把這一步交個哦
webhook
來做啊
但是
webhook
不管哪個平台都會帶一點參數,是以我們在配置中心自己定義下。
@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
@RestController
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Autowired
private RestTemplate restTemplate;
@RequestMapping("/bus-refresh")
public String busRefresh() {
HttpHeaders httpHeaders=new HttpHeaders();
httpHeaders.add("content-type","application/json;charset=UTF-8");
return restTemplate.postForObject("http://localhost:8888/actuator/bus-refresh", httpHeaders, String.class);
}
}
然後在對應代碼平台的
webhook
中配置一下你自定義的 url ,這樣就實作了你送出一次就動态更新啦。
此文章僅限入門,切記啊不會用找不到多去官網看文檔!