Spring Cloud 系列之 Bus 消息總線

什麼是消息總線

  

  消息代理中間件構建一個共用的消息主題讓全部微服務實例訂閱,當該消息主題產生消息時會被全部微服務實例監聽和消費。html

  消息代理又是什麼?消息代理是一個消息驗證、傳輸、路由的架構模式,主要用來實現接收和分發消息,並根據設定好的消息處理流來轉發給正確的應用。它在微服務之間起到通訊調度做用,減小了服務之間的依賴。git

  

什麼是 Spring Cloud Bus

  

  

  Spring Cloud Bus 是 Spring Cloud 體系內的消息總線,用來鏈接分佈式系統的全部節點。github

  Spring Cloud Bus 將分佈式的節點用輕量的消息代理(RibbitMQ、Kafka)鏈接起來。能夠經過消息代理廣播配置文件的更改,或服務之間的通信,也能夠用於監控。解決了微服務數據變動,及時同步的問題。web

  官方文檔:https://cloud.spring.io/spring-cloud-static/spring-cloud-bus/2.2.1.RELEASE/reference/html/spring

  

何時使用 Spring Cloud Bus

  

  微服務通常都採用集羣方式部署,並且在高併發下常常須要對服務進行擴容、縮容、上線、下線的操做。好比咱們須要更新配置,又或者須要同時失效全部服務器上的某個緩存,須要向全部相關的服務器發送命令,此時就能夠選擇使用 Spring Cloud Bus 了。bootstrap

  總的來講,就是在咱們須要把一個操做散發到全部後端相關服務器的時候,就能夠選擇使用 Spring Cloud Bus 了。後端

  接下來咱們經過 Spring Cloud Bus 實現微服務架構的配置刷新。緩存

  

環境準備

  

  RibbitMQ v3.8.2 地址:192.168.10.101服務器

  

  bus-demo 聚合工程。SpringBoot 2.2.4.RELEASESpring Cloud Hoxton.SR1網絡

  • eureka-server:註冊中心
  • eureka-server02:註冊中心
  • config-server:配置中心服務端
  • config-server02:配置中心服務端
  • order-service:訂單服務(配置中心客戶端)
  • order-service02:訂單服務(配置中心客戶端)

  

  配置文件 order-service-prod.yml

spring:
  application:
    name: order-service # 應用名稱

# 配置 Eureka Server 註冊中心
eureka:
  instance:
    prefer-ip-address: true       # 是否使用 ip 地址註冊
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
  client:
    service-url:                  # 設置服務註冊中心地址
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

# 自定義配置
name: order-service-prod
password: root

  

Spring Cloud Bus 實現配置刷新

  

客戶端發起通知

  

  點擊連接觀看:客戶端發起通知視頻(獲取更多請關注公衆號「哈嘍沃德先生」)

  

  消息總線(Bus)的典型應用場景就是配置中心客戶端刷新。

  咱們在學習 Spring Cloud Config 配置中心時給你們講了基於 Actuator 的配置刷新,當時的案例只有一個 Config Client,咱們可使用 Webhook,設置手動刷新都不算太費事,可是若是客戶端比較多的狀況下,一個一個去手動刷新未免有點複雜,這種方案就不太適合了。使用 Spring Cloud Bus 能夠完美解決這一問題。

  藉助 Spring Cloud Bus 的廣播功能,讓 Config Client 都訂閱配置更新事件,當配置更新時,觸發其中一個端的更新事件,Spring Cloud Bus 就把此事件廣播到其餘訂閱客戶端,以此來達到批量更新。

  1. Webhook 監聽被觸發,給 ConfigClient A 發送 bus-refresh 請求刷新配置
  2. ConfigClient A 讀取 ConfigServer 中的配置,而且發送消息給 Bus
  3. Bus 接收消息後廣播通知其餘 ConfigClient
  4. 其餘 ConfigClient 收到消息從新讀取最新配置

  

添加依賴

  

  Config Client 添加 spring cloud starter bus amqp 依賴。

<!-- spring cloud starter bus amqp 依賴 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

  

配置文件

  

  配置文件須要配置 消息隊列bus-refresh 自動刷新端點。/actuator/bus-refresh 端點會清除 @RefreshScope 緩存從新綁定屬性。

  Config Client 的 bootstrap.yml 核心配置。

spring:
  cloud:
    config:
      name: order-service # 配置文件名稱,對應 git 倉庫中配置文件前半部分
      label: master # git 分支
      profile: prod # 指定環境
      discovery:
        enabled: true # 開啓
        service-id: config-server # 指定配置中心服務端的 service-id
  # 消息隊列
  rabbitmq:
    host: 192.168.10.101
    port: 5672
    username: guest
    password: guest
    virtual-host: /

# 度量指標監控與健康檢查
management:
  endpoints:
    web:
      base-path: /actuator    # 訪問端點根路徑,默認爲 /actuator
      exposure:
        include: bus-refresh  # 須要開啓的端點
        #exclude:             # 不須要開啓的端點

  

測試

  

查看端點

  

  訪問:http://localhost:9091/actuator 能夠看到已經開啓了 bus-refresh 自動刷新端點。

  

  訪問:http://localhost:9091/namehttp://localhost:9092/name 結果以下:

  

修改 Git 倉庫配置

  

  修改 Git 倉庫配置信息以下:

# 自定義配置
name: order-service-prod-1.0

  

自動刷新

  

  刷新頁面發現結果並未改變,沒事正常。

  經過 Post 方式調用任意客戶端的自動刷新端點:http://localhost:9091/actuator/bus-refresh 再次訪問結果以下:

  

查看隊列

  

  再來觀察一下消息隊列的 UI 界面,發現多了一個 springCloudBus 的交換機。

  該交換機下綁定了兩個隊列對應咱們的兩個 Config Client。

  

客戶端發起通知缺陷

  

  • 打破了微服務的職責單一性。微服務自己是業務模塊,它本不該該承擔配置刷新的職責。
  • 破壞了微服務各節點的對等性。
  • 存在必定的侷限性。例如,微服務在遷移時,它的網絡地址經常會發生變化,此時若是想要作到自動刷新,就不得不修改Webhook 的配置。

  

服務端發起通知

  

  點擊連接觀看:服務端發起通知視頻(獲取更多請關注公衆號「哈嘍沃德先生」)

  

  爲了解決客戶端發起通知缺陷,咱們改用服務端發起通知。

  1. Webhook監聽被觸發,給 ConfigServer 發送 bus-refresh 請求刷新配置
  2. ConfigServer 發送消息給 Bus
  3. Bus 接收消息後廣播通知全部 ConfigClient
  4. 各 ConfigClient 收到消息從新讀取最新配置

  

添加依賴

  

  Config Server 添加 spring cloud starter bus amqp 依賴。

<!-- spring cloud starter bus amqp 依賴 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

  

配置文件

  

  配置文件須要配置 消息隊列bus-refresh 自動刷新端點。/actuator/bus-refresh 端點會清除 @RefreshScope 緩存從新綁定屬性。

  Config Server 的 application.yml 核心配置。

spring:
  application:
    name: config-server # 應用名稱
  cloud:
    config:
      server:
        git:
          uri: https://github.com/imrhelloworld/config-repo # 配置文件所在倉庫地址
          #username:             # Github 等產品的登陸帳號
          #password:             # Github 等產品的登陸密碼
          #default-label: master # 配置文件分支
          #search-paths:         # 配置文件所在根目錄
  # 消息隊列
  rabbitmq:
    host: 192.168.10.101
    port: 5672
    username: guest
    password: guest
    virtual-host: /

# 配置 Eureka Server 註冊中心
eureka:
  instance:
    prefer-ip-address: true       # 是否使用 ip 地址註冊
    instance-id: ${spring.cloud.client.ip-address}:${server.port} # ip:port
  client:
    service-url:                  # 設置服務註冊中心地址
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

# 度量指標監控與健康檢查
management:
  endpoints:
    web:
      base-path: /actuator    # 訪問端點根路徑,默認爲 /actuator
      exposure:
        include: bus-refresh  # 須要開啓的端點
        #exclude:             # 不須要開啓的端點

  

測試

  

查看端點

  

  訪問:http://localhost:8888/actuator 能夠看到已經開啓了 bus-refresh 自動刷新端點。

  

  訪問:http://localhost:9091/namehttp://localhost:9092/name 結果以下:

  

修改 Git 倉庫配置

  

  修改 Git 倉庫配置信息以下:

# 自定義配置
name: order-service-prod-2.0

  

自動刷新

  

  刷新頁面發現結果並未改變,沒事正常。

  經過 Post 方式調用任意服務端的自動刷新端點:http://localhost:8888/actuator/bus-refresh 再次訪問結果以下:

  

查看隊列

  

  再來觀察一下消息隊列的 UI 界面,發現多了一個 springCloudBus 的交換機。

  該交換機下綁定了四個隊列對應咱們的兩個 Config Server 和兩個 Config Client。

  

局部刷新

  

  假設有這樣一種場景,咱們開發了一個新的功能,此時須要對該功能進行測試。咱們只但願其中一個微服務的配置被更新,等功能測試完畢,正式部署線上時再更新至整個集羣。可是因爲全部微服務都受 Spring Cloud Bus 的控制,咱們更新了其中一個微服務的配置,就會致使其餘服務也被通知去更新配置。這時候局部刷新的做用就體現出來了。

  

刷新指定服務

  

  修改 Git 倉庫配置信息以下:

# 自定義配置
name: order-service-prod-3.0

  

  經過 Post 方式調用任意服務端的自動刷新端點:http://localhost:8888/actuator/bus-refresh/order-service:9091 再次訪問結果以下:

  9091 端口的客戶端已經更新配置。

  9092 端口的客戶端沒有更新配置。

  

刷新指定集羣

  

  假設如今功能測試完畢,須要正式部署線上更新至整個集羣。可是因爲 Spring Cloud Bus 控制着多個微服務集羣(訂單微服務、商品微服務等),而咱們只想更新指定集羣下的配置,這個時候就可使用 Bus 提供的通配符更新方案。

  修改 Git 倉庫配置信息以下:

# 自定義配置
name: order-service-prod-4.0

  

  經過 Post 方式調用任意服務端的自動刷新端點:http://localhost:8888/actuator/bus-refresh/order-service:** 再次訪問結果以下:

  至此 Bus 消息總線全部的知識點就講解結束了。

本文采用 知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協議

你們能夠經過 分類 查看更多關於 Spring Cloud 的文章。

  

🤗 您的點贊轉發是對我最大的支持。

📢 掃碼關注 哈嘍沃德先生「文檔 + 視頻」每篇文章都配有專門視頻講解,學習更輕鬆噢 ~

相關文章
相關標籤/搜索