Spring Cloud系列教程(十一):消息总线Spring Cloud Bus(Finchley版本)

官方文档: https://cloud.spring.io/spring-cloud-static/spring-cloud-bus/2.2.1.RELEASE/reference/html/#bus-endpoints

一、前言

在上一篇文章中,我们实现了基于Spring Cloud Config 分布式配置中心实现配置文件分离开来,统一放入GitSVN等版本控制软件中管理,但在上一篇文章中,有个问题: 当Git/SVN版本控制库中的微服务配置文件信息发生更改时,Config-Server端可以实时的收到最新的通知发生响应的刷新,但是Config-Client端无法动态感知这种变化,而最后我们提到的是通过使用手动方式发送/refresh接口请求Config-Client端,从而实现Git仓库中的内容修改时,触发Config-Client端应用程序的属性做出对应的更新。但是,若所有Git/SVN上触发的操作均需要手动去调用/refresh接口刷新Config-Client端应用程序的属性做出对应的更新,会变的越来越难以维护,而消息代理中间件(RabbitMQ或Kafka)是解决该问题最为合适的方案,也就是本篇将要实现的基于消息总线Spring Cloud Bus实现动态刷新。

本文还是基于上一篇文章来实现。Spring Cloud系列教程(十):分布式配置中心Spring Cloud Config(Finchley版本) ,不清楚的同学请先阅读上一篇文章,本篇会在上一篇文章源码的基础上稍作修改,然后需要加入RabbitMQ依赖信息,同时我们需要安装RabbitMQ,关于RabbitMQ安装和开启比较简单,百度下文章也很多,需要引入的RabbitMQ依赖如下:

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

注意: 另外,如果你是通过刷新config-client端来广播配置文件的变化,那么config-client端还需要引入actuator监控依赖,由于引入的config-server端spring-cloud-config-server依赖中已经默认集成了,所以config-server端无需引入。

   <!-- 监控 -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

二、什么是Spring Cloud Bus消息总线

Spring Cloud Bus 是 Spring Cloud 体系内的消息总线,是Spring Cloud微服务全家桶中的一个组件,用来连接分布式系统的所有服务节点。将分布式的服务节点用轻量的消息代理(RibbitMQ、Kafka)连接起来。可以通过消息代理广播配置文件的更改实现全部节点的更新,或服务之间的通讯,也可以用于监控。解决了微服务数据变更,及时同步的问题。

三、Spring Cloud Bus如何工作

使用Spring Cloud Bus来实现配置文件的动态更新原理很简单,如下图:

  • 刷新服务端流程
    在这里插入图片描述
    在上述整张流程图中:

  • 没有引入Bus消息总线之前的流程:
    在Config-Server在启动的时候,首先会去远程Git仓库上读取配置文件信息,默认会持久化一份配置文件到硬盘上,同时还会在JVM内存中缓存一份,然后再返回给微服务Service-A/微服务Service-B/微服务Service-C;当微服务Service-A和微服务Service-B、微服务Service-C,也就是Config-Client端在启动的时候,会从Config-Server中加载读取各自服务对应的配置文件信息,在这个流程中,Config-Server充当了一个中间缓存的作用。

  • 引入Bus消息总线之后的工作流程:
    当远程Git仓库配置文件更新后,我向Config-Server中发送一个/bus/refresh请求,Config-Server收到这个请求之后,会将这个请求通过RabbitMQ广播出去,这样所有的微服务就都收到这个请求了,微服务收到这个请求之后就会自动去更新自己的配置文件。在这个系统中,从RabbitMQ的角度来看,所有的微服务都是一样的,所以这个/bus/refresh请求我们也可以在Config-Client节点上发出,一样能够实现配置文件动态更新的效果,但是这样做就破坏了我们微服务的结构,使得微服务节点之间有了区别,其实微服务本身是业务模块,它本不应该承担配置刷新的职责。所以刷新配置的请求我们还是放在Config-Server上来做比较合适。

四、准备工作

1. 工程准备

本篇博客基于上一篇博客源码做修改,下载地址: https://github.com/Thinkingcao/SpringCloudLearning/tree/master/springcloud-config

  • springcloud-eureka-server : eureka注册中心,端口8888
  • springcloud-config-server: 分布式配置中心服务端,端口8080
  • springcloud-config-client: 分布式配置中心客户端,端口8081

在eureka-server、cpnfig-server、config-client 三个工程中都加入RabbitMQ依赖信息:
在这里插入图片描述

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

2. congig-server配置文件

配置文件需要配置 消息队列 和 bus-refresh 自动刷新端点。/actuator/bus-refresh 端点会清除 @RefreshScope 缓存重新绑定属性。
在这里插入图片描述

#端口号
server:
  port: 8080

#定义服务名称(服务注册到eureka名称)
spring:
  application:
    name: app-config-server
  #Spring Cloud Config Server端配置
  cloud:
    config:
      server:
        git:
          #远程存储库的URI地址。
          uri: https://gitee.com/Thinkingcao/springcloud-config-repo
          #使用远程Git仓库验证用户名。
          username: xxxxxxxxx
          #使用远程Git仓库密码。
          password: xxxxxxxxx
          #指定远程Git仓库的分支
          default-label: master
          #指定本地仓库地址用来存储获取远程Git上的配置文件
          basedir: G:\temp\path\config-properties
          ##git仓库地址下的相对地址,可以配置多个,用,分割,也就是配置文件所在根目录文件夹名称
          search-paths: config-respo
      #标记以指示启用配置服务器发现(配置服务器URL将通过发现查找)。
      discovery:
        enabled: true
    #bus配置,标记以打开跟踪
    bus:
      trace:
        enabled: true
        
  #rabbitmq配置
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: admin
    password: 111111
    virtual-host: /

#在此指定服务注册中心地址,将当前服务注册到eureka注册中心上
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8888/eureka
    #启动注册操作,该值默认为true。若设置为fasle将不会启动注册操作。是否需要去检索寻找服务,默认是true
    register-with-eureka: true
    #是否需要从eureka上获取注册信息
    fetch-registry: true

#暴露bus刷新配置的端点
management:
  #关闭安全校验
  security:
    enable: false
  #暴露端点
  endpoints:
    web:
      exposure:
        include: bus-refresh  # 需要开启的端点
        #exclude:             # 不需要开启的端点
      base-path: /actuator   # 访问端点根路径,默认为 /actuator

3. config-client配置文件

#服务端口号
server:
  port: 8081
#定义服务名称(服务注册到eureka名称)
spring:
  application:
    name: order
  #cloud config配置
  cloud:
    config:
      name: ${spring.application.name}
      profile: dev   #profile对应config server所获取的配置文件中的{profile}
      label: master  #指定Git仓库的分支,对应config server所获取的配置文件的{label}
      discovery:
        #标记以指示启用配置服务器发现(配置服务器URL将通过发现查找)
        enabled: true
        #读取config-server注册地址
        service-id: app-config-server
      #uri: http://127.0.0.1:8080/

    #bus配置,标记以打开跟踪
    bus:
      trace:
        enabled: true
  #rabbitmq配置
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: admin
    password: 111111
    virtual-host: /

#在此指定服务注册中心地址,将当前服务注册到eureka注册中心上
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8888/eureka
    #启动注册操作,该值默认为true。若设置为fasle将不会启动注册操作。是否需要去检索寻找服务,默认是true
    register-with-eureka: true
    #是否需要从eureka上获取注册信息
    fetch-registry: true

4. eureka-server配置文件

#服务端口号
server:
  port: 8888
#定义服务名称(服务注册到eureka名称)
spring:
  application:
    name: app-thinkingcao-eureka
    #bus配置,标记以打开跟踪
    bus:
      trace:
        enabled: true
  #rabbitmq配置
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: admin
    password: 111111
    virtual-host: /

eureka:
  instance:
    #Eureka注册中心ip地址
    hostname: 127.0.0.1
  client:
    serviceUrl:
      #注册地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    #表示是否需要将自己注册给自己的注册中心,因为自己是注册中心,单机版本时不需要,设置为false(集群的时候需要是为true)
    register-with-eureka: false
    #因为自己是注册中心,不需要去检索服务信息,单机版本时不需要,设置为false(集群的时候需要是为true)
    fetch-registry: false
  #Eureka自我保护机制
  server:
    #关闭eureka自我保护机制false(默认为true)
    enable-self-preservation: false
    # 清理间隔(单位毫秒,默认是60*1000)
    eviction-interval-timer-in-ms: 2000

5. RabbitMQ添加用户

输入用户名密码就可以创建了,tags表示用户标签,相当于角色,可选值有management、none、policymaker、monitoring和administrator,不同取值所对应的权限区别如下:

  • none
    1.不能访问 management plugin

  • management
    用户可以通过AMQP做的任何事外加:
    1.列出自己可以通过AMQP登入的virtual hosts
    2.查看自己的virtual hosts中的queues, exchanges 和 bindings
    3.查看和关闭自己的channels 和 connections
    4.查看有关自己的virtual hosts的“全局”的统计信息,包含其他用户在这些virtual hosts中的活动

  • policymaker
    management可以做的任何事外加:
    1.查看、创建和删除自己的virtual hosts所属的policies和parameters

  • monitoring
    management可以做的任何事外加:
    1.列出所有virtual hosts,包括他们不能登录的virtual hosts
    2.查看其他用户的connections和channels
    3.查看节点级别的数据如clustering和memory使用情况
    4.查看真正的关于所有virtual hosts的全局的统计信息

  • administrator
    policymaker和monitoring可以做的任何事外加:
    1.创建和删除virtual hosts
    2.查看、创建和删除users
    3.查看创建和删除permissions
    4.关闭其他用户的connections

在这里插入图片描述

五、基于Webhook实现全自动化配置刷新

消息总线(Bus)的典型应用场景就是配置中心客户端刷新。Spring Cloud官方推荐的是基于 Actuator 的配置刷新,这种方式还是需要人工干预,手动调用actuator/refresh接口,只不过我们只需要刷新一个Config-Server端点, Spring Cloud Bus 的代理(RabbitMQ或者KafKa)广播功能,让 Config Client 都订阅配置更新事件,当配置更新时,触发其中一个端的更新事件,Spring Cloud Bus 就把此事件广播到其他订阅客户端,以此来达到批量更新,当使用Spring Cloud Bus 时,Config-Client的数量我们就无需关心了。

1. Webhook配置

WebHooks相当于是一个钩子函数,我们可以配置当向Git(GitLab/GitHub/Gitee)仓库push代码时触发这个钩子函数,自动调用"http://localhost:8080/actuator/bus-refresh/{destination}"请求,帮助我们自动发送一个POST请求刷新Config-Client和Config-Server,这里以Gitee为例来介绍下其使用方式,这里当我们向配置仓库push代码时就会自动刷新服务配置了。

  • 添加Webhook配置如下
    在这里插入图片描述
  • 使用Webhook 整体流程
  1. Webhook 监听被触发,给 ConfigClient A 发送 bus-refresh 请求刷新配置
  2. ConfigClient A 读取 ConfigServer 中的配置,并且发送消息给 Bus
  3. Bus 接收消息后广播通知其他 ConfigClient
  4. 其他 ConfigClient 收到消息重新读取最新配置

关于Webhook的使用,这里只做介绍,因为个人觉得当配置文件发生Push更改的时候,手动调用一下"bus-refresh/"接口即可,没什么工作量,没有必要使用Webhook。

六、查看RabbitMQ

首先开启RabbitMQ和RabbitMQ的UI界面插件,然后启动eureka-server、cpnfig-server、config-client这3个服务,访问RabbitMQ服务的UI界面: http://localhost:15672, 账号密码默认:guest/guest,显示如下:

新增了3个队列:
在这里插入图片描述
新增一个springCloudBus交换机
在这里插入图片描述
点开springCloudBus发现交换机绑定了3个队列:
在这里插入图片描述

七、测试

1. 查看端点是否开启

访问:http://localhost:9091/actuator 可以看到已经开启了 bus-refresh自动刷新端点
在这里插入图片描述
Git仓库配置文件值如下:
在这里插入图片描述
访问: http://localhost:8081/message , 响应结果如下:

https://thinkingcao.blog.csdn.net/
在这里插入图片描述

2. 更改Git配置文件值

blog:
  url: www.baidu.com

3. 刷新Config-Server端接口

PostMan访问: http://localhost:8080/actuator/bus-refresh 即可。
在这里插入图片描述
然后再次访问: http://localhost:8081/message,显示刷新后的结果,如下:
在这里插入图片描述

4. 总结

八、源码

源码: https://github.com/Thinkingcao/SpringCloudLearning/tree/master/springcloud-bus

Thinkingcao CSDN认证博客专家 Java Spring Boot 架构
CSDN2019年度博客之星、博客专家,专注架构、Java、SpringBoot、SpringCloud、Spring、微服务、分布式等领域
©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值