Spring Cloud筆記-Spring Cloud Bus消息總線(十四)

1.概述

Spring Cloud Bus是用來將分佈式系統的結點與輕量級消息系統連接起來的框架,它整合了Java事件處理機制和消息中間件的功能,Spring Cloud Bus目前支持的MQ有:RAbbitMQ和Kafka。Spring Cloud Bus可以使Spring Cloud Config實現配置的動態刷新。

觀察下圖,運維發送/bus/refresh的POST請求給其中一個Client,Client將消息發送給消息總線,最初收到POST請求的Client拉取最新的配置信息,監聽Spring Cloud Bus的其他Client收到消息後,也去配置中心拉取最新配置信息。這種模式是不推薦的,下面會說原因。

Spring Cloud Bus能管理和傳播分佈式系統間的消息,類似一個分佈式執行器,可用於廣播狀態更改、事件推送等,也可以作爲微服務之間的通信信道。

在微服務架構系統中,通常會使用輕量級的消息代理來構建一個共用的消息主題,讓所有的微服務實例都連接上來,這個主題中產生的消息會被所有實例監聽和消費,所以稱爲消息總線。在總線上的實例還可以發送消息給總線,讓總線上的其他監聽者獲取消息。

觀察下圖,運維發送/bus/refresh請求給配置中心,配置中心會獲取最新的配置文件,併發送一個消息給消息總線,監聽消息總線的其他Client會收到消息,並從配置中心拉取最新的配置文件。這種模式是推薦使用的。

用戶向Config Server發送update的post請求,Config Server更新配置並把消息發送到總線的Topic中,Config Client實例監聽MQ中同一個Topic(默認是Spring Cloud Bus),所有監聽同一個Topic的服務就都能收到通知,然後更新自身的配置。

2.RabbitMQ環境配置

1.Window版本

RabbitMQ服務器是用Erlang語言編寫,需要下載Erlang運行環境,下載地址:http://erlang.org/download/otp_win64_21.3.exe,然後安裝RabbitMQ,下載地址:https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.14/rabbitmq-server-3.7.14.exe,在RabbitMQ的sbin目錄下,cmd下運行rabbitmq-plugins enable rabbitmq_management添加可視化插件,運行之後,可以在安裝目錄看到幾個插件,啓動RabbitMQ Service-start,在瀏覽器訪問http://localhost:15672/,輸入用戶名和密碼,都是guest。

2.Linux版本

使用Docker安裝RabbitMQ,輸入命令docker pull rabbitmq:management拉取rabbitmq鏡像,記得選擇帶management的,否則沒有管理後臺。使用命令docker run -d -p 5672:5672 -p 15672:15672 rabbitmq:management啓動RabbitMQ服務。瀏覽器訪問http://192.168.0.123:15672/,即可看到管理後臺,輸入用戶名和密碼,都是guest。

3.Spring Cloud Bus動態刷新全局廣播

爲了演示廣播的效果,我們還需要一個Config-Client,於是參考cloud-config-client-3355創建cloud-config-client-3366。記得修改端口號,其他地方和cloud-config-client-3355幾乎沒什麼變化,爲了區分具體Client,在ConfigClientController的請求中,把端口號輸出。

上面提到了兩種方案:一種是發給某一個ConfigClient,另一種是發給ConfigServer,這裏推薦後者。原因如下:

  1. ConfigClient也是一個微服務,它有自己的業務需要處理,如果把刷新配置的工作放在它上面,就破壞了單一職責原則。
  2. 如果在某臺ConfigClient加了刷新功能,它處理自身業務邏輯可能會受到影響,可能會拖慢本身的業務。
  3. 如果ConfigClient遷移,要對地址進行修改,增加工作量,相對來說,ConfigServer遷移概率小一些。

所以,我們選擇發送/bus/refresh給ConfigServer,ConfigServer獲取最新配置信息後發送消息給Bus,監聽Bus的ConfigClient收到消息後,從ConfigServer上拉取最新的配置信息。

修改cloud-config-server-3344添加消息總線支持,pom.xml中加入spring-cloud-starter-bus-amqp的座標。

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

修改cloud-config-server-3344指定MQ的信息,並暴露bus-refresh端口。

server:
  port: 3344
spring:
  application:
    name: cloud-config-center
  cloud:
    config:
      server:
        git:
          uri: https://github.com/WangShaoYang/Spring-Cloud.git # Github上的倉庫地址
          search-paths: # 搜索目錄,即配置文件的目錄
            - cloud-config-center-3344/
      label: master # 讀取分支
  rabbitmq: # 指定MQ的信息
    host: 192.168.0.123
    port: 5672
    username: guest
    password: guest
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/
management:
  endpoints:
    web:
      exposure:
        include: 'bus-refresh' # 暴露bus-refresh端口

修改cloud-config-client-3355和cloud-config-client-3366添加消息總線支持,pom.xml中加入spring-cloud-starter-bus-amqp的座標,和cloud-config-server-3344的pom.xml裏是一樣的。

修改cloud-config-client-3355和cloud-config-client-3366的bootstrap.yml,指明MQ的信息,並暴露bus-refresh端點,MQ的信息和cloud-config-server-3344保持一致即可,另外注意縮進對齊,因爲cloud-config-client-3355和cloud-config-client-3366之前暴露的端點信息是"*"了,所以這裏就不用改了。

啓動RabbitMQ服務,先後啓動Eureka7001,CloudServer3344,CloudConfig3355,CloudConfig3366模塊,如果啓動太快報錯,就一個一個的啓動。啓動完成後,訪問http://eureka7001.com:7001/查看微服務註冊信息,訪問RabbitMQ管理後臺,確定RabbitMQ正常啓動了。訪問http://localhost:3344/master/config-dev.ymlhttp://localhost:3355/configInfohttp://localhost:3366/configInfo確保都能正常訪問後,去GitHub上修改config-dev.yml的內容,由運維工程師發送如下命令(如正常情況下,沒有任何返回信息),注意發送給ConfigServer這臺機器。

C:\Users\WangShaoYang>curl -X POST "http://localhost:3344/actuator/bus-refresh"

刷新成功後,再次訪問http://localhost:3344/master/config-dev.ymlhttp://localhost:3355/configInfohttp://localhost:3366/configInfo,可以發現它們獲取到了最新的配置信息。查看RabbitMQ的管理後臺,查看Exchanges標籤會看到一個springCloudBus的Topic,正是通過這個Topic,3355和3366客戶端接收到刷新消息,自我刷新它們的配置文件。

4.Spring Cloud Bus動態刷新定點通知

上面的消息通知是發送給了所有監聽springCloudBus的Client,如果只希望通知某些Client,就需要在發送curl請求的時候,做一些改動,將實際想發送的Client指定一下即可。

比如,我修改配置中心的配置文件,只希望3355Client生效,那麼發送的url爲:curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"。說明一下,這裏的請求實際上還是發送給ConfigServer,也就是發送給localhost:3344,和之前不同的是,在bus-refresh後,帶了一個參數,表明RabbitMQ需要通知給微服務名稱(對應spring.application.name的值,也是註冊進Eureka中微服務的名稱)爲config-client,端口號(對應server.port的值)爲3355的微服務。

演示一下,在GitHub上修改config-dev.yml的內容,發送通知給ConfigServer,讓其通知3355Client更新配置信息(正常情況下,沒有任何返回信息)。

C:\Users\WangShaoYang>curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"

訪問http://localhost:3344/master/config-dev.ymlhttp://localhost:3355/configInfohttp://localhost:3366/configInfo查看效果,3344信息更新,3355信息更新,3366信息沒變,試驗成功。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章