7--SpringCloud搭建訊息匯流排
先回顧一下,在之前的Spring Cloud Config的介紹中,我們還留了一個懸念:如何實現對配置資訊的實時更新。雖然,我們已經能夠通過/refresh
介面和Git倉庫的Web Hook來實現Git倉庫中的內容修改觸發應用程式的屬性更新。但是,若所有觸發操作均需要我們手工去維護Web Hook中的應用位置的話,這隨著系統的不斷擴張,會變的越來越難以維護,而訊息代理中介軟體是解決該問題最為合適的方案。是否還記得我們在介紹訊息代理中的特點時有提到過這樣一個功能:訊息代理中介軟體可以將訊息路由到一個或多個目的地。利用這個功能,我們就能完美的解決該問題,下面我們來說說Spring Cloud Bus中的具體實現方案。
RabbitMQ實現
準備工作
這裡我們不做新的應用,但需要用到上一章中,我們已經實現的關於Spring Cloud Config的幾個工程,若讀者對其還不瞭解,建議先閱讀
config-eurekaServer:服務註冊中心
config-server:配置了Git倉庫,並註冊到了Eureka的服務端。
config-client:通過Eureka發現Config Server的客戶端,應用名為ghghspace,用來訪問配置伺服器以獲取配置資訊。該應用中提供了一個/from
介面,它會獲取5--SpringCloud--Config /ghghspace-dev.properties
在本地安裝好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來逐個進行重新整理的問題。