消息總線


如何實現對配置信息的實時更新

消息代理中間件可以將消息路由到一個或多個目的地。利用這個功能,我們就能完美的解決該問題

RabbitMQ實現

 config-client修改pom.xml增加spring-cloud-starter-bus-amqp模塊

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

 

 

在配置文件中增加關於RabbitMQ的連接和用戶信息

spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=springcloud spring.rabbitmq.password=123456

 

 

啟動config-server,再啟動兩個config-clien(分別在不同的端口上)

可以在config-client-eureka中的控制台中看到如下內容,在啟動時候,客戶端程序多了一個/bus/refresh請求。

o.s.b.a.e.mvc.EndpointHandlerMapping     : Mapped "{[/bus/refresh],methods=[POST]}" onto public void org.springframework.cloud.bus.endpoint.RefreshBusEndpoint.refresh(java.lang.String)

 

  • 先訪問兩個config-client的/from請求,會返回當前config-repo/didispace-dev.properties中的from屬性。
  • 接着,我們修改config-repo/didispace-dev.properties中的from屬性值,並發送POST請求到其中的一個/bus/refresh
  • 最后,我們再分別訪問啟動的兩個config-client的/from請求,此時這兩個請求都會返回最新的config-repo/didispace-dev.properties中的from屬性。

上面已經能夠通過Spring Cloud Bus來實時更新總線上的屬性配置了。

原理分析

我們通過使用Spring Cloud Bus與Spring Cloud Config的整合,並以RabbitMQ作為消息代理,實現了應用配置的動態更新。

 

 

訪問/bus/refresh接口。此時,“Service A”的實例3就會將刷新請求發送到消息總線中,該消息事件會被“Service A”的實例1和實例2從總線中獲取到,並重新從Config Server中獲取他們的配置信息,從而實現配置信息的動態更新。

指定刷新范圍

通過向服務實例請求Spring Cloud Bus的/bus/refresh接口,從而觸發總線上其他服務實例的/refresh。但是有些特殊場景下(比如:灰度發布),我們希望可以刷新微服務中某個具體實例的配置。

Spring Cloud Bus對這種場景也有很好的支持:/bus/refresh接口還提供了destination參數,用來定位具體要刷新的應用程序。比如,我們可以請求/bus/refresh?destination=customers:9000,此時總線上的各應用實例會根據destination屬性的值來判斷是否為自己的實例名,若符合才進行配置刷新,若不符合就忽略該消息

destination參數除了可以定位具體的實例之外,還可以用來定位具體的服務。定位服務的原理是通過使用Spring的PathMatecher(路徑匹配)來實現,比如:/bus/refresh?destination=customers:**,該請求會觸發customers服務的所有實例進行刷新

 

 架構優化

在之前的架構中,服務的配置更新需要通過向具體服務中的某個實例發送請求,再觸發對整個服務集群的配置更新。雖然能實現功能,但是這樣的結果是,我們指定的應用實例就會不同於集群中的其他應用實例,這樣會增加集群內部的復雜度,不利於將來的運維工作,比如:我們需要對服務實例進行遷移,那么我們不得不修改Web Hook中的配置等。所以我們要盡可能的讓服務集群中的各個節點是對等的

 

 

我們主要做了這些改動:

  1. 在Config Server中也引入Spring Cloud Bus,將配置服務端也加入到消息總線中來。
  2. /bus/refresh請求不在發送到具體服務實例上,而是發送給Config Server,並通過destination參數來指定需要更新配置的服務或實例。

我們的服務實例就不需要再承擔觸發配置更新的職責。同時,對於Git的觸發等配置都只需要針對Config Server即可,從而簡化了集群上的一些維護工作。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM