乐趣区

关于java:SpringCloud之消息总线

后面的话 】书接上文 SpringCloud 之 Config,如果没有看过能够先移步去看一下。在上一篇文章中提到了配置刷新的问题,如果须要刷新配置就须要客户端执行refresh,咱们能够利用webhook 的机制每次提交代码发送申请来刷新客户端,当客户端越来越多的时候,须要每个客户端都执行一遍,这种计划就不太适宜了。应用 Spring Cloud Bus 能够完满解决这一问题。


壹、Spring Cloud Bus 的简介

Spring cloud bus 通过轻量音讯代理连贯各个散布的节点。这会用在播送状态的变动(例如配置变动)或者其余的音讯指令。Spring bus 的一个核心思想是通过分布式的启动器对 spring boot 利用进行扩大,也能够用来建设一个多个利用之间的通信频道。目前惟一实现的形式是用 AMQP 音讯代理作为通道,同样个性的设置(有些取决于通道的设置)在更多通道的文档中。

贰、解决方案

计划一:

  • Spring cloud bus 被国内很多都翻译为音讯总线,也挺形象的。大家能够将它了解为治理和流传所有分布式我的项目中的音讯既可,其实实质是利用了 MQ 的播送机制在分布式的零碎中流传音讯,目前罕用的有 Kafka 和 RabbitMQ。利用 bus 的机制能够做很多的事件,其中配置核心客户端刷新就是典型的利用场景之一,咱们用一张图来形容 bus 在配置核心应用的机制。

依据此图咱们能够看出利用 Spring Cloud Bus 做配置更新的步骤:

    1、提交代码触发 post 给客户端 A 发送 /actuator/bus-refresh
    2、客户端 A 接管到申请从 Server 端更新配置并且发送给 Spring Cloud Bus
    3、Spring Cloud bus 接到音讯并告诉给其它客户端
    4、其它客户端接管到告诉,申请 Server 端获取最新配置
    5、全副客户端均获取到最新的配置

计划二:

  • 在计划一中咱们曾经达到了利用音讯总线触发一个客户端 /actuator/bus-refresh, 而刷新所有客户端的配置的目标。但这种形式并不优雅。起因如下:

       突破了微服务的职责单一性。微服务自身是业务模块,它本不应该承当配置刷新的职责。毁坏了微服务各节点的对等性。有肯定的局限性。例如,微服务在迁徙时,它的网络地址经常会发生变化,此时如果想要做到主动刷新,那就不得不批改 WebHook 的配置。

    因而咱们将计划一的架构模式略微扭转一下

    这时 Spring Cloud Bus 做配置更新步骤如下:

      1、提交代码触发 post 申请给 bus/refresh
      2、server 端接管到申请并发送给 Spring Cloud Bus
      3、Spring Cloud bus 接到音讯并告诉给其它客户端
      4、其它客户端接管到告诉,申请 Server 端获取最新配置
      5、全副客户端均获取到最新的配置

    上面咱们就采纳计划二来革新咱们的工程,这样的话咱们在 server 端的代码做一些改变,来反对 bus/refresh

叁、革新服务端

  • 革新上文的 config 的服务端子工程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> 配置服务端 </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   # 服务端口号
spring:
  application:
    name: lovinconfigserver     # 服务名称
  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/   # 注册到的 eureka 服务地址

肆、革新配置客户端

  • 革新上文的 config 的服务端子工程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> 配置生产端 </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 的相干配置
  1. 批改 bootstrap.yml 增加连贯 rabbitmq 的配置
server:
  port: 8807   # 服务端口号
spring:
  application:
    name: lovinconfigclient     # 服务名称
  security:
    basic:
      enabled: true
    user:
      name: lovin
      password: ${REGISTRY_SERVER_PASSWORD:lovin}
#eureka:
#  client:
#    serviceUrl:
#      defaultZone: http://lovin:lovin@localhost:8881/eureka/   # 注册到的 eureka 服务地址
  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/   # 留神在高可用的时候须要见注册核心配置移到该文件中,在 application.yml 中见会读取不到配置

伍、启动测试

  • 1. 首先顺次启动 lovin-eureka-server、lovin-econfig-server、lovin-econfig-client
  • 2. 查看 lovin-econfig-server 查问配置

  • 3. 查看 lovin-econfig-client 查问配置

  • 4. 批改配置,并提交见 token 的值由 lovin 改为 lovinupdate

  • 5. 再次查看 lovin-econfig-server 查问配置

  • 6. 再次查看 lovin-econfig-client 查问配置

  • 7. 刷新音讯总线

因为 api 变更,url 由老版本的 /bus/refresh 变为 actuator/bus-refresh

  • 8. 再次查看 lovin-econfig-client 查问配置

咱们能够看到曾经刷新胜利,至此音讯总线配置曾经实现

陆、部分刷新

某些场景下(例如灰度公布),咱们可能只想刷新局部微服务的配置,此时可通过 /actuator/bus-refresh 端点的 destination 参数来定位要刷新的应用程序。

  • 例如:/actuator/bus-refresh?destination=customers:8000,这样音讯总线上的微服务实例就会依据 destination 参数的值来判断是否须要要刷新。其中,customers:8000 指的是各个微服务的 ApplicationContext ID。destination 参数也能够用来定位特定的微服务。
  • 例如:/actuator/bus-refresh?destination=customers:**,这样就能够触发 customers 微服务所有实例的配置刷新。

  • 最初的最初是本博客的源码, 欢送关注这一套 SpringCloud 的实际
退出移动版