7--SpringCloud搭建消息總線
先回顧一下,在之前的Spring Cloud Config的介紹中,我們還留了一個懸念:如何實現對配置信息的實時更新。雖然,我們已經能夠通過/refresh接口和Git倉庫的Web Hook來實現Git倉庫中的內容修改觸發應用程序的屬性更新。但是,若所有觸發操作均需要我們手工去維護Web Hook中的應用位置的話,這隨著系統的不斷擴張,會變的越來越難以維護,而消息代理中間件是解決該問題最為合適的方案。是否還記得我們在介紹消息代理中的特點時有提到過這樣一個功能:消息代理中間件可以將消息路由到一個或多個目的地。利用這個功能,我們就能完美的解決該問題,下面我們來說說Spring Cloud Bus中的具體實現方案。
RabbitMQ實現
準備工作
這里我們不做新的應用,但需要用到上一章中,我們已經實現的關于Spring Cloud Config的幾個工程,若讀者對其還不了解,建議先閱讀
6--SpringCloud搭建分布式配置中心(續-高可用性)
config-eurekaServer:服務注冊中心
config-server:配置了Git倉庫,并注冊到了Eureka的服務端。
config-client:通過Eureka發現Config Server的客戶端,應用名為ghghspace,用來訪問配置服務器以獲取配置信息。該應用中提供了一個/from接口,它會獲取5--SpringCloud--Config /ghghspace-dev.properties中的from屬性返回。
在本地安裝好RabbitMQ服務;
擴展config-client應用
修改pom.xml增加spring-cloud-starter-bus-amqp模塊
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Brixton.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在配置文件中增加關于RabbitMQ的連接和用戶信息
server.port=7002 #對應前配置文件中的{application}部分 spring.application.name=ghghspace eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/ #參數設置為true,開啟通過服務來訪問Config Server的功能 spring.cloud.config.discovery.enabled=true #指定配置中心的實例名 spring.cloud.config.discovery.serviceId=config-server #對應前配置文件中的{profile}部分 spring.cloud.config.profile=dev #對應前配置文件的git分支 spring.cloud.config.label=master #mq鏈接信息 spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=gh spring.rabbitmq.password=123456
啟動config-server,再啟動兩個config-client(分別在不同的端口上,比如7002、7003),我們可以在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請求,會返回當前的from屬性。 - 接著,我們修改
中的from屬性值,并發送POST請求到其中的一個5--SpringCloud--Config/ghghspace-dev.properties/bus/refresh。 - 最后,我們再分別訪問啟動的兩個config-client的
/from請求,此時這兩個請求都會返回最新的中的from屬性。5--SpringCloud--Config/ghghspace-dev.properties
到這里,我們已經能夠通過Spring Cloud Bus來實時更新總線上的屬性配置了。
原理分析
我們通過使用Spring Cloud Bus與Spring Cloud Config的整合,并以RabbitMQ作為消息代理,實現了應用配置的動態更新。
整個方案的架構如上圖所示,其中包含了Git倉庫、Config Server、以及微服務“Service A”的三個實例,這三個實例中都引入了Spring Cloud Bus,所以他們都連接到了RabbitMQ的消息總線上。
當我們將系統啟動起來之后,“Service A”的三個實例會請求Config Server以獲取配置信息,Config Server根據應用配置的規則從Git倉庫中獲取配置信息并返回。
此時,若我們需要修改“Service A”的屬性。首先,通過Git管理工具去倉庫中修改對應的屬性值,但是這個修改并不會觸發“Service A”實例的屬性更新。我們向“Service A”的實例3發送POST請求,訪問/bus/refresh接口。此時,“Service A”的實例3就會將刷新請求發送到消息總線中,該消息事件會被“Service A”的實例1和實例2從總線中獲取到,并重新從Config Server中獲取他們的配置信息,從而實現配置信息的動態更新。
而從Git倉庫中配置的修改到發起/bus/refresh的POST請求這一步可以通過Git倉庫的Web Hook來自動觸發。由于所有連接到消息總線上的應用都會接受到更新請求,所以在Web Hook中就不需要維護所有節點內容來進行更新,從而解決了通過Web Hook來逐個進行刷新的問題。
源碼下載:7--SpringCloud搭建消息總線


浙公網安備 33010602011771號