Spring Cloud第十二篇 | 訊息匯流排Bus
本文是Spring Cloud專欄的第十二篇文章,瞭解前十一篇文章內容有助於更好的理解本文:
-
Spring Cloud第一篇 | Spring Cloud前言及其常用元件介紹概覽
-
Spring Cloud第二篇 | 使用並認識Eureka註冊中心
-
Spring Cloud第三篇 | 搭建高可用Eureka註冊中心
-
Spring Cloud第四篇 | 客戶端負載均衡Ribbon
-
Spring Cloud第五篇 | 服務熔斷Hystrix
-
Spring Cloud第六篇 | Hystrix儀表盤監控Hystrix Dashboard
-
Spring Cloud第七篇 | 宣告式服務呼叫Feign
-
Spring Cloud第八篇 | Hystrix叢集監控Turbin
-
Spring Cloud第九篇 | 分散式服務跟蹤Sleuth
-
Spring Cloud第十篇 | 分散式配置中心Config
-
Spring Cloud第十一篇 | 分散式配置中心高可用
一、前言
由於在沒有使用訊息匯流排的時候,我們如果需要修改某個配置,如果涉及修改的微服務節點比較多,我們需要手動的一個節點一個節點的重新整理非常麻煩,在微服務架構的系統中,我們通常會使用輕量級的訊息代理來構建一個共用的訊息主題讓系統中所有微服務例項都連線上來,由於該主題中產生的訊息會被所有例項監聽和消費,所以我們稱它為訊息匯流排。在總線上的各個例項都可以方便地廣播一些需要讓其他連線在該主題上的例項都知道的訊息,例如配置資訊的變更或者其他一些管理操作等。
由於訊息匯流排在微服務架構系統中被廣泛使用,所以它同配置中心一樣,幾乎是微服務架構中的必備元件。Spring Cloud作為微服務架構綜合性的解決方案,對此自然也有自己的實現,通過使用Spring Cloud Bus可以非常容易地搭建起訊息匯流排,同時實現了一些訊息匯流排中的常用功能,比如配合Spring Cloud Config實現微服務應用配置資訊的動態更新等,架構如圖所示:
目前版本,Spring Cloud Bus僅支援兩款中介軟體產品,RabbitMQ和Kafka,本案例使用RabbitMQ實現Spring Cloud Bus的應用
RabbitMQ安裝步驟以及使用自行百度啦。。。
二、整合訊息匯流排bus
1、修改以前的springcloud-config-server,springcloud-config-client塊新增訊息匯流排依賴,actuator依賴在前幾篇案例中已經在父模組(springcloud-learn)中引入,此處不需要再次引入
<!--spring cloud bus 整合rabbitmq --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
2、rabbitmq服務地址:http://47.112.11.147:15672/ rabbitmq使用者名稱為:admin密碼為:123456
3、在springcloud-config-server模組基礎上往application.yml新增bus和rabbitmq的相關配置以及暴露bus-refresh端點
spring: cloud: bus: #控制bus訊息匯流排是否能用 enabled: true #開啟bus追蹤 trace: enabled: true rabbitmq: addresses: 47.112.11.147 port: 5672 username: admin password: 123456 virtual-host: / management: endpoints: web: exposure: include: ["info","health","bus-refresh"]
4、在springcloud-config-client模組基礎上往application.yml新增rabbitmq相關配置就行了
spring: rabbitmq: addresses: 47.112.11.147 port: 5672 username: admin password: 123456 virtual-host: /
5、啟動配置中心服務端(springcloud-config-server)檢視bus相應的轉換器Exchange以及Type對應的topic,並且同時在控制檯上通過日誌可以看到bus-refresh端點暴露出來了
RabbitMQ的Topic模式如圖所示:
如果不懂RabbitMQ的話也不影響你的Bus使用
檢視rabbitmq控制檯看到bus相應對列建立了
檢視繫結關係,springcloud bus相應對列已經繫結到了springcloud bus轉換器上了
6、啟動配置中心客戶端(springcloud-config-client)可以看到該對列也繫結到spirngcloud bus轉換器上了
7、我們在複製springcloud-config-client的配置,新建檔案bootstrap-configclient8882.yml配置檔案如下,創鍵啟動類啟動SpringcloudConfigClient8882Application
server: port: 8882 spring: application: name: springcloud-config-client cloud: config: #uri則表示配置中心的地址 #uri: http://localhost:8888 #注:config 客戶端在沒有 spring.cloud.config.name屬性的時候,服務端{application} 獲取的是客戶端 #spring.application.name的值,否則,獲取的是 spring.cloud.config.name的值。 #1)、當沒有spring.cloud.config.name時,客戶端獲取的是spring.application.name 所對應的git庫中的檔案,並且只能 #獲取一個檔案, #2)、當一個專案中有需求要獲取多個檔案時,就需要用到spring.cloud.config.name這個屬性,以逗號分割 name: configclient profile: dev #label對應了label部分 label: master # username: coding-farmer # password: 123456 discovery: #表示開啟通過服務名來訪問config-server enabled: true #則表示config-server的服務名 service-id: springcloud-config-server #失敗快速響應 fail-fast: true retry: #配置重試次數,預設為6 max-attempts: 6 #初始重試間隔時間,預設1000ms initial-interval: 1000 #間隔乘數,預設1.1 multiplier: 1.1 #最大間隔時間,預設2000ms max-interval: 2000 rabbitmq: addresses: 47.112.11.147 port: 5672 username: admin password: 123456 virtual-host: / eureka: client: service-url: defaultZone: http://localhost:8700/eureka #客戶端每隔30秒從Eureka服務上更新一次服務資訊 registry-fetch-interval-seconds: 30 #需要將我的服務註冊到eureka上 register-with-eureka: true #需要檢索服務 fetch-registry: true #心跳檢測檢測與續約時間 instance: #告訴服務端,如果我10s之內沒有給你發心跳,就代表我故障了,將我剔除掉,預設90s #Eureka服務端在收到最後一次心跳之後等待的時間上限,單位為秒,超過則剔除(客戶端告訴服務端按照此規則等待自己) lease-expiration-duration-in-seconds: 10 #每隔2s向服務端傳送一次心跳,證明自已依然活著,預設30s #Eureka客戶端向服務端傳送心跳的時間間隔,單位為秒(客戶端告訴服務端自己會按照該規則) lease-renewal-interval-in-seconds: 2 # 啟用ip配置 這樣在註冊中心列表中看見的是以ip+埠呈現的 prefer-ip-address: true # 例項名稱 最後呈現地址:ip:2002 instance-id: ${spring.cloud.client.ip-address}:${server.port} management: endpoints: web: exposure: include: ["info","health","refresh"]
8、碼雲倉庫值預設如下
訪問http://localhost:8881/index
訪問http://localhost:8882/index
9、修改倉庫內容
然後向springcloud-config-server服務bus-refresh端點發送POST請求http://localhost:8888/actuator/bus-refresh
10、再次訪問客戶端8881,882顯示如下
三、指定重新整理範圍
在上面案例中我們看到當你觸發/actuator/bus-refresh端點時,它就會重新整理所有例項的服務配置,有時候我們可能只需要重新整理某個具體的例項。
Spring Cloud Bus對這種場景也有很好的支援,/actuator/bus-refresh/{destination}介面提供了一個destination引數,RESTFUL風格請求,用來定位具體要重新整理的應用程式。比如:我們可以請求/actuator/bus-refresh/springcloud-config-client:8882,此時總線上的各應用例項會根據destination屬性的值來判斷是否為自己的例項名,若符合才進行配置重新整理,若不符合就忽略該訊息。
destination引數除了可以定位具體的例項之外,還可以用來定位具體的服務。定位服務的原理是通過使用Spring的PathMatecher(路徑匹配)來實現的,比如/actuator/bus-refresh/springcloud-config-client:**,該請求會觸發customers服務的所有例項進行重新整理。
1、以前倉庫資訊為:
例如:修改為如下
2、向http://localhost:8888/actuator/bus-refresh/springcloud-config-client:8882傳送POST請求
3、訪問客戶端8881,8882服務內容如下
四、總結
使用/actuator/bus-refresh傳送到我們其中一個config-client中也能重新整理配置(前提是該客戶端的bus-refresh端點需要暴露出來),但是這樣這個例項就跟其他例項不一樣了,它還額外承擔了重新整理配置的功能。所以,我們將傳送post請求重新整理配置的任務交由config-server配置服務中心來處理,這樣所有服務例項都是對等的,由配置服務中心傳送訊息通知訊息匯流排更新整個叢集中的配置。這樣,服務例項就不需要再承擔觸發配置更新的任務。儘可能讓服務叢集中的各個節點是對等的將來利於運維工作。
詳細參考案例原始碼:https://gitee.com/coding-farmer/spirngcloud-learn