SpringCloud之消息總線

前面的話】書接上文SpringCloud之Config,如果沒有看過(guò)可以先移步去看一下。在上一篇文章中提到了配置刷新的問題,如果需要刷新配置就需要客戶端執(zhí)行refresh,我們可以利用webhook的機(jī)制每次提交代碼發(fā)送請(qǐng)求來(lái)刷新客戶端,當(dāng)客戶端越來(lái)越多的時(shí)候,需要每個(gè)客戶端都執(zhí)行一遍,這種方案就不太適合了。使用Spring Cloud Bus可以完美解決這一問題。


壹、Spring Cloud Bus的簡(jiǎn)介

Spring cloud bus通過(guò)輕量消息代理連接各個(gè)分布的節(jié)點(diǎn)。這會(huì)用在廣播狀態(tài)的變化(例如配置變化)或者其他的消息指令。Spring bus的一個(gè)核心思想是通過(guò)分布式的啟動(dòng)器對(duì)spring boot應(yīng)用進(jìn)行擴(kuò)展,也可以用來(lái)建立一個(gè)多個(gè)應(yīng)用之間的通信頻道。目前唯一實(shí)現(xiàn)的方式是用AMQP消息代理作為通道,同樣特性的設(shè)置(有些取決于通道的設(shè)置)在更多通道的文檔中。

貳、解決方案

方案一:

  • Spring cloud bus被國(guó)內(nèi)很多都翻譯為消息總線,也挺形象的。大家可以將它理解為管理和傳播所有分布式項(xiàng)目中的消息既可,其實(shí)本質(zhì)是利用了MQ的廣播機(jī)制在分布式的系統(tǒng)中傳播消息,目前常用的有Kafka和RabbitMQ。利用bus的機(jī)制可以做很多的事情,其中配置中心客戶端刷新就是典型的應(yīng)用場(chǎng)景之一,我們用一張圖來(lái)描述bus在配置中心使用的機(jī)制。
方案一流程圖

根據(jù)此圖我們可以看出利用Spring Cloud Bus做配置更新的步驟:

    1、提交代碼觸發(fā)post給客戶端A發(fā)送/actuator/bus-refresh
    2、客戶端A接收到請(qǐng)求從Server端更新配置并且發(fā)送給Spring Cloud Bus
    3、Spring Cloud bus接到消息并通知給其它客戶端
    4、其它客戶端接收到通知,請(qǐng)求Server端獲取最新配置
    5、全部客戶端均獲取到最新的配置

方案二:

  • 在方案一中我們已經(jīng)到達(dá)了利用消息總線觸發(fā)一個(gè)客戶端/actuator/bus-refresh,而刷新所有客戶端的配置的目的。但這種方式并不優(yōu)雅。原因如下:
   打破了微服務(wù)的職責(zé)單一性。微服務(wù)本身是業(yè)務(wù)模塊,它本不應(yīng)該承擔(dān)配置刷新的職責(zé)。
   破壞了微服務(wù)各節(jié)點(diǎn)的對(duì)等性。
   有一定的局限性。例如,微服務(wù)在遷移時(shí),它的網(wǎng)絡(luò)地址常常會(huì)發(fā)生變化,此時(shí)如果想要做到自動(dòng)刷新,那就不得不修改WebHook的配置。

因此我們將方案一的架構(gòu)模式稍微改變一下

方案二流程圖

這時(shí)Spring Cloud Bus做配置更新步驟如下:

  1、提交代碼觸發(fā)post請(qǐng)求給bus/refresh
  2、server端接收到請(qǐng)求并發(fā)送給Spring Cloud Bus
  3、Spring Cloud bus接到消息并通知給其它客戶端
  4、其它客戶端接收到通知,請(qǐng)求Server端獲取最新配置
  5、全部客戶端均獲取到最新的配置

下面我們就采用方案二來(lái)改造我們的工程,這樣的話我們?cè)趕erver端的代碼做一些改動(dòng),來(lái)支持bus/refresh

叁、改造服務(wù)端

  • 改造上文的config的服務(wù)端子工程lovin-config-server,添加RabbitMQ的依賴。下面是改造后的主要的pom依賴:
<parent>
        <artifactId>lovincloud</artifactId>
        <groupId>com.eelve.lovincloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lovin-config-server</artifactId>
    <packaging>jar</packaging>
    <name>lovinconfigserver</name>
    <version>0.0.1</version>
    <description>配置服務(wù)端</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-client</artifactId>
            <version>2.1.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 添加rabbitmq的連接配置
server:
  port: 8886   # 服務(wù)端口號(hào)
spring:
  application:
    name: lovinconfigserver     # 服務(wù)名稱
  security:
    basic:
      enabled: true
    user:
      name: lovin
      password: ${REGISTRY_SERVER_PASSWORD:lovin}
  cloud:
    config:
      server:
        git:
          uri: https://github.com/lovinstudio/lovincloud
          search-paths: lovin-config-repo
      label: master
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
eureka:
  client:
    serviceUrl:
      defaultZone: http://lovin:lovin@localhost:8881/eureka/   # 注冊(cè)到的eureka服務(wù)地址

肆、改造配置客戶端

  • 改造上文的config的服務(wù)端子工程lovin-config-client,添加RabbitMQ的依賴。下面是改造后的主要的pom依賴:
    <parent>
        <artifactId>lovincloud</artifactId>
        <groupId>com.eelve.lovincloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lovin-config-client</artifactId>
    <packaging>jar</packaging>
    <name>lovinconfigclient</name>
    <version>0.0.1</version>
    <description>配置消費(fèi)端</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-client</artifactId>
            <version>2.1.6</version>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.cloud</groupId>-->
<!--            <artifactId>spring-cloud-config-server</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>
        <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>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  • 添加連接rabbitmq的相關(guān)配置
  1. 修改bootstrap.yml添加連接rabbitmq的配置
server:
  port: 8807   # 服務(wù)端口號(hào)
spring:
  application:
    name: lovinconfigclient     # 服務(wù)名稱
  security:
    basic:
      enabled: true
    user:
      name: lovin
      password: ${REGISTRY_SERVER_PASSWORD:lovin}
#eureka:
#  client:
#    serviceUrl:
#      defaultZone: http://lovin:lovin@localhost:8881/eureka/   # 注冊(cè)到的eureka服務(wù)地址
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
  1. 修改application.yml開啟消息跟蹤
spring:
  cloud:
    config:
      name: lovin-config
      profile: dev
      #uri: http://localhost:8886/
      #label: master
      discovery:
        enabled: true
        service-id: lovinconfigserver
    bus:
      trace:
        enabled: true
eureka:
  client:
    serviceUrl:
      defaultZone: http://lovin:lovin@localhost:8881/eureka/   # 注意在高可用的時(shí)候需要見注冊(cè)中心配置移到該文件中,在application.yml中見會(huì)讀取不到配置

伍、啟動(dòng)測(cè)試

  • 1.首先依次啟動(dòng)lovin-eureka-server、lovin-econfig-server、lovin-econfig-client
  • 2.查看lovin-econfig-server查詢配置
查看lovin-econfig-server查詢配置
  • 3.查看lovin-econfig-client查詢配置
查看lovin-econfig-client查詢配置
  • 4.修改配置,并提交見token的值由lovin改為lovinupdate
修改token
  • 5.再次查看lovin-econfig-server查詢配置
再次查詢服務(wù)端
  • 6.再次查看lovin-econfig-client查詢配置
再次查詢客戶端
  • 7.刷新消息總線
    由于api變更,url由老版本的/bus/refresh變?yōu)閍ctuator/bus-refresh
屬性消息總線
  • 8.再次查看lovin-econfig-client查詢配置
再次查看客戶端配置

我們可以看到已經(jīng)刷新成功,至此消息總線配置已經(jīng)完成

陸、局部刷新

某些場(chǎng)景下(例如灰度發(fā)布),我們可能只想刷新部分微服務(wù)的配置,此時(shí)可通過(guò)/actuator/bus-refresh端點(diǎn)的destination參數(shù)來(lái)定位要刷新的應(yīng)用程序。

  • 例如:/actuator/bus-refresh?destination=customers:8000,這樣消息總線上的微服務(wù)實(shí)例就會(huì)根據(jù)destination參數(shù)的值來(lái)判斷是否需要要刷新。其中,customers:8000指的是各個(gè)微服務(wù)的ApplicationContext ID。destination參數(shù)也可以用來(lái)定位特定的微服務(wù)。
  • 例如:/actuator/bus-refresh?destination=customers:**,這樣就可以觸發(fā)customers微服務(wù)所有實(shí)例的配置刷新。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud Bus:消息總線 Spring Cloud Bus 使用輕量級(jí)的消息代理來(lái)連接微服務(wù)架構(gòu)...
    NIceBoy閱讀 362評(píng)論 0 0
  • 首先:歡迎各位學(xué)習(xí)java和大數(shù)據(jù)的程序員朋友們加入Java交流學(xué)習(xí)群: 721506929,群內(nèi)提供免費(fèi)的架構(gòu)學(xué)...
    伯雅之英閱讀 451評(píng)論 0 0
  • 久違的晴天,家長(zhǎng)會(huì)。 家長(zhǎng)大會(huì)開好到教室時(shí),離放學(xué)已經(jīng)沒多少時(shí)間了。班主任說(shuō)已經(jīng)安排了三個(gè)家長(zhǎng)分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,822評(píng)論 16 22
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友。感恩相遇!感恩不離不棄。 中午開了第一次的黨會(huì),身份的轉(zhuǎn)變要...
    余生動(dòng)聽閱讀 10,858評(píng)論 0 11
  • 可愛進(jìn)取,孤獨(dú)成精。努力飛翔,天堂翱翔。戰(zhàn)爭(zhēng)美好,孤獨(dú)進(jìn)取。膽大飛翔,成就輝煌。努力進(jìn)取,遙望,和諧家園。可愛游走...
    趙原野閱讀 3,508評(píng)論 1 1

友情鏈接更多精彩內(nèi)容