spring cloud 使用spring cloud bus自動刷新配置

Spring Cloud Bus提供了批量刷新配置的機制,它使用輕量級的消息代理(例如RabbitMQ、Kafka等)鏈接分佈式系統的節點,這樣就能夠經過Spring Cloud Bus廣播配置的變化或者其餘的管理指令。使用Spring Cloud Bus後的架構如圖9-2所示。java

圖9-2 使用Spring Cloud Bus的架構圖git

由圖可知,微服務A的全部實例經過消息總線鏈接到了一塊兒,每一個實例都會訂閱配置更新事件。當其中一個微服務節點的/bus/refresh端點被請求時,該實例就會向消息總線發送一個配置更新事件,其餘實例得到該事件後也會更新配置。web

下面咱們以RabbitMQ爲例,爲你們講解如何使用Spring Cloud Bus實現配置的自動刷新。spring

(1) 安裝RabbitMQ。RabbitMQ的安裝很是簡單,本書再也不贅述。bootstrap

(2) 建立項目microservice-config-client-refresh-cloud-bus 安全

(3) 爲項目添加spring-cloud-starter-bus-amqp 的依賴。網絡

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

(4) 在bootstrap.yml中添加如下內容:架構

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

  management:
    security:
      enabled: false #是否開啓actuator安全認證mvc

 

測試

(1) 啓動microservice-config-serverapp

(2) 啓動microservice-config-client-refresh-cloud-bus,可發現此時控制檯打印相似於如下的內容:

[           main] 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)

說明此時有一個/bus/refresh 端點

(3) 將microservice-config-client-refresh-cloud-bus的端口改爲8082,再啓動一個節點。

(4) 訪問http://localhost:8081/profile ,可得到結果:dev-1.0。

(4) 將git倉庫中的microservice-foo-dev.properties文件內容改成profile=dev-1.0-bus

(5) 發送POST請求到其中一個Config Client節點的的/bus/refresh端點,例如:

curl -X POST http://localhost:8081/bus/refresh

藉助Git倉庫的WebHook,咱們就可輕鬆實現配置的自動刷新。如圖9-3所示。

圖9-3 Git WebHooks設置

藉助Git倉庫的WebHook,咱們就可輕鬆實現配置的自動刷新。如圖9-3所示。(6) 訪問兩個Config Client節點的/profile端點,會發現兩個節點都會返回dev-1.0-bus ,說明配置內容已被刷新。

局部刷新

某些場景下(例如灰度發佈),咱們可能只想刷新部分微服務的配置,此時可經過/bus/refresh端點的destination參數來定位要刷新的應用程序。

例如:/bus/refresh?destination=customers:9000 ,這樣消息總線上的微服務實例就會根據destination參數的值來判斷是否須要要刷新。其中,customers:9000 指的是各個微服務的ApplicationContext ID。

destination參數也能夠用來定位特定的微服務。例如:/bus/refresh?destination=customers:**,這樣就能夠觸發customers微服務全部實例的配置刷新。

擴展閱讀:關於ApplicationContext ID

默認狀況下,ApplicationContext ID是spring.application.name:server.port,詳見org.springframework.boot.context.ContextIdApplicationContextInitializer.getApplicationId(ConfigurableEnvironment)方法。

http://www.itmuch.com/spring-cloud-code-read/spring-cloud-code-read-spring-cloud-bus/

架構改進

在前面的示例中,咱們經過請求某個微服務的/bus/refresh端點的方式來實現配置刷新,但這種方式並不優雅。緣由以下:

(1) 打破了微服務的職責單一性。微服務自己是業務模塊,它本不該該承擔配置刷新的職責。

(2) 破壞了微服務各節點的對等性。

(3) 有必定的侷限性。例如,微服務在遷移時,它的網絡地址經常會發生變化,此時若是想要作到自動刷新,那就不得不修改WebHook的配置。

咱們不妨改進一下咱們的架構。

圖9-4 使用Spring Cloud Bus的架構圖

如圖9-4,咱們將Config Server也加入到消息總線中,並使用Config Server的/bus/refresh端點來實現配置的刷新。這樣,各個微服務只須要關注自身的業務,而再也不承擔配置刷新的職責。

1.在springcloud-configServer中配置bus,加入pom依賴

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

2.springcloud-configServer中配置bus ym文件

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
  management:
    security:
      enabled: false #是否開啓actuator安全認證

3.在微服務端springcloud-ssmServer配置bus接收

pom.xml

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

application.properties

#mq
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest

management.security.enabled=false

在須要自動刷新的位置加入@RefreshScope 例如

package com.pupeiyuan.controller; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RefreshScope public class ConfigClientController { @Value("${multiple.datasource.master.InitialSize}") private String profile; @GetMapping("/profile") public String getProfile() { return this.profile; } }

利用webhook自動請求,配置/bus/refresh到springcloud-configServer項目,springcloud-configServer在利用bus傳播特性,經過mq傳播到指定客戶端進行更新

跟蹤總線事件

一些場景下,咱們可能但願知道Spring Cloud Bus事件傳播的細節。此時,咱們能夠跟蹤總線事件(RemoteApplicationEvent的子類都是總線事件)。

跟蹤總線事件很是簡單,只需設置spring.cloud.bus.trace.enabled=true ,這樣在/bus/refresh端點被請求後,訪問/trace端點就可得到相似以下的結果:

{ "timestamp": 1481098786017, "info": { "signal": "spring.cloud.bus.ack", "event": "RefreshRemoteApplicationEvent", "id": "66d172e0-e770-4349-baf7-0210af62ea8d", "origin": "microservice-foo:8081", "destination": "**" } },{ "timestamp": 1481098779073, "info": { "signal": "spring.cloud.bus.sent", "type": "RefreshRemoteApplicationEvent", "id": "66d172e0-e770-4349-baf7-0210af62ea8d", "origin": "microservice-config-server:8080", "destination": "**:**" } }...

 

這樣,咱們就可清晰地知道事件的傳播細節。

相關文章
相關標籤/搜索