前面兩篇文章我們聊了Spring Cloud Config配置中心,當(dāng)我們?cè)诟耮ithub上面的配置以后,如果想要獲取到最新的配置,需要手動(dòng)刷新或者利用webhook的機(jī)制每次提交代碼發(fā)送請(qǐng)求來(lái)刷新客戶端,客戶端越來(lái)越多的時(shí)候,需要每個(gè)客戶端都執(zhí)行一遍,這種方案就不太適合了。使用Spring Cloud Bus(國(guó)人很形象的翻譯為消息總線,我比較喜歡叫消息巴士)可以完美解決這一問(wèn)題。(了解源碼可+求求: 1791743380)
1. Spring Cloud Bus
Spring cloud bus通過(guò)輕量消息代理連接各個(gè)分布的節(jié)點(diǎn)。這會(huì)用在廣播狀態(tài)的變化(例如配置變化)或者其他的消息指令。Spring bus的一個(gè)核心思想是通過(guò)分布式的啟動(dòng)器對(duì)spring boot應(yīng)用進(jìn)行擴(kuò)展,也可以用來(lái)建立一個(gè)多個(gè)應(yīng)用之間的通信頻道。目前唯一實(shí)現(xiàn)的方式是用AMQP消息代理作為通道,同樣特性的設(shè)置(有些取決于通道的設(shè)置)在更多通道的文檔中。
大家可以將它理解為管理和傳播所有分布式項(xiàng)目中的消息既可,其實(shí)本質(zhì)是利用了MQ的廣播機(jī)制在分布式的系統(tǒng)中傳播消息,目前常用的有Kafka和RabbitMQ。利用bus的機(jī)制可以做很多的事情,其中配置中心客戶端刷新就是典型的應(yīng)用場(chǎng)景之一,我們用一張圖來(lái)描述bus在配置中心使用的機(jī)制。

根據(jù)此圖我們可以看出利用Spring Cloud Bus做配置更新的步驟:
提交代碼觸發(fā)post給客戶端A發(fā)送bus/refresh
客戶端A接收到請(qǐng)求從Server端更新配置并且發(fā)送給Spring Cloud Bus
Spring Cloud bus接到消息并通知給其它客戶端
其它客戶端接收到通知,請(qǐng)求Server端獲取最新配置
全部客戶端均獲取到最新的配置
2. 項(xiàng)目示例
我們使用上一篇文章中的config-server和config-client來(lái)進(jìn)行改造,mq使用rabbitmq來(lái)做示例。
2.1 客戶端config-client
2.1.1 添加依賴
org.springframework.cloudspring-cloud-starter-bus-amqp
需要多引入spring-cloud-starter-bus-amqp包,增加對(duì)消息總線的支持
2.1.2 配置文件 bootstrap.properties
spring.application.name=spring-cloud-config-clientserver.port=8081spring.cloud.config.name=springcloud-configspring.cloud.config.profile=devspring.cloud.config.label=masterspring.cloud.config.discovery.enabled=truespring.cloud.config.discovery.serviceId=spring-cloud-config-servereureka.client.service-url.defaultZone=http://localhost:8761/eureka/management.endpoints.web.exposure.include=*## 開啟消息跟蹤spring.cloud.bus.trace.enabled=truespring.rabbitmq.host=127.0.0.1spring.rabbitmq.port=5672spring.rabbitmq.username=spring.rabbitmq.password=
配置文件需要增加RebbitMq的相關(guān)配置,這樣客戶端代碼就改造完成了。
2.1.3 測(cè)試
依次啟動(dòng)eureka,config-serve,config-client。
修改config-client啟動(dòng)配置,同時(shí)在8081和8082端口啟動(dòng)服務(wù)。
啟動(dòng)完成后,瀏覽器分別訪問(wèn)連接:http://localhost:8081/hello,?http://localhost:8082/hello, 可以發(fā)現(xiàn)頁(yè)面顯示的內(nèi)容都是:hello dev update1,說(shuō)明客戶端都已經(jīng)讀取到了server端的內(nèi)容。
現(xiàn)在我們更新github上的配置文件,將配置內(nèi)容改為hello dev update,先訪問(wèn)一下http://localhost:8081/hello,可以看到頁(yè)面依然顯示為:hello dev update1。
我們對(duì)端口為8081的服務(wù)發(fā)送一個(gè)/actuator/bus-refresh的POST請(qǐng)求,在win10下使用下面命令來(lái)模擬webhook。
curl -X POST http://localhost:8081/actuator/bus-refresh
注意:?在springboot2.x的版本中刷新路徑為:/actuator/bus-refresh,在springboot1.5.x的版本中刷新路徑為:/bus/refresh。
執(zhí)行完成后,我們先訪問(wèn)http://localhost:8082/hello,可以看到頁(yè)面打印內(nèi)容已經(jīng)變?yōu)椋篽ello dev update,這樣說(shuō)明,我們8081端口的服務(wù)已經(jīng)把更新后的信息通過(guò)rabbitmq推送給了8082端口的服務(wù),這樣我們就實(shí)現(xiàn)了圖一中的示例。
2.2 改進(jìn)版
上面的流程中,雖然我們做到了利用一個(gè)消息總線觸發(fā)刷新,而刷新所有客戶端配置的目的,但是這種方式并不合適,如下:
打破了微服務(wù)的職責(zé)單一性。微服務(wù)本身是業(yè)務(wù)模塊,它本不應(yīng)該承擔(dān)配置刷新的職責(zé)。
破壞了微服務(wù)各節(jié)點(diǎn)的對(duì)等性。
如果客戶端ip有變化,這時(shí)我們就需要修改WebHook的配置。
我們可以將上面的流程改進(jìn)一下:

這時(shí)Spring Cloud Bus做配置更新步驟如下:
提交代碼觸發(fā)post給Server端發(fā)送bus/refresh
Server端接收到請(qǐng)求并發(fā)送給Spring Cloud Bus
Spring Cloud bus接到消息并通知給其它客戶端
其它客戶端接收到通知,請(qǐng)求Server端獲取最新配置
全部客戶端均獲取到最新的配置
這樣的話我們?cè)趕erver端的代碼做一些改動(dòng),來(lái)支持/actuator/bus-refresh
和上面的client端的改動(dòng)基本一致
2.2.1 添加依賴
org.springframework.cloudspring-cloud-starter-bus-amqp
需要多引入spring-cloud-starter-bus-amqp包,增加對(duì)消息總線的支持
2.2.2 配置文件application.yml
server:? port:8080spring:? application:? ? name:spring-cloud-config-server? cloud:? ? config:? ? ? server:? ? ? ? git:? ? ? ? ? uri:https://github.com/meteor1993/SpringCloudLearning? ? ? ? ? search-paths:chapter6/springcloud-config? ? ? ? ? username:? ? ? ? ? password:? rabbitmq:? ? host:217.0.0。1? ? port:5672? ? username:? ? password:management:? endpoints:? ? web:? ? ? exposure:? ? ? ? include:"*"eureka:? client:? ? service-url:? ? ? defaultZone:http://localhost:8761/eureka/
配置文件需要增加RebbitMq的相關(guān)配置,actuator開啟所有訪問(wèn)。
2.2.3 測(cè)試
依次啟動(dòng)eureka,config-serve,config-client。
修改config-client啟動(dòng)配置,同時(shí)在8081和8082端口啟動(dòng)服務(wù)。
按照上面的測(cè)試方式,訪問(wèn)兩個(gè)客戶端測(cè)試均可以正確返回信息。同樣修改配置文件,將值改為:hello im dev update并提交到倉(cāng)庫(kù)中。在win10下使用下面命令來(lái)模擬webhook。
curl -X POST http://localhost:8081/actuator/bus-refreshCOPY
執(zhí)行完成后,依次訪問(wèn)兩個(gè)客戶端,返回:hello im dev update。說(shuō)明三個(gè)客戶端均已經(jīng)拿到了最新配置文件的信息,這樣我們就實(shí)現(xiàn)了上圖中的示例。