SpringCloud(Greenwich版)Bus消息总线

推荐以下稳定版本号:

Spring Boot: 2.1.9.RELEASE

Spring Cloud: Greenwich.SR3

一、Bus简介

是什么?

  Spring Cloud Bus 使用轻量级的消息代理(目前只支持两种,RabbitMQ 和 Kafka)连接分布式系统的节点,这样就可以广播传播状态的更改(例如配置的更新)或者其他的管理指令。可将 Spring Cloud Bus 想象成一个分布式 Spring Boot Actuator,也可以当做微服务间的通信通道。

为什么被称为消息总线?

  在微服务系统架构中,通常会使用轻量级的消息代理来构建一个共用的消息主题(订阅某学校的微信公众号 topic),并让系统中所有微服务实例(可以理解为所有学生 micro-service)都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称之为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。

基本原理:

  Config Client 实例都监听 MQ 中同一个主题 (topic),当一个服务刷新数据的时候,它会把这个信息放入主题 (topic) 中,这样其它监听同一个主题 (topic) 的服务就能够得到通知,然后去更新自身配置。

登录RabbitMQ Web页面后,在我们的 Exchanges (RabbitMQ交换机) 中,会有一个默认的名称:springCloudBus

 

 

二、设计思想两种通知

第一种方式:利用消息总线触发一个客户端/bus/refresh端点,而刷新所有客户端的配置。

 

  1. 提交配置出发 POST 请求调用客户端A (Config Client) 的 /bus/refresh 接口

  2. 客户端A (Config Client) 收到请求从配置中心 (Config Server) 更新配置并且发送给 Bus 消息总线

  3. Bus 消息总线接收消息并通知给其他连线在总线上的客户端,所有总线上的客户端均能接收到消息

  4. 其他客户端接收到消息,请求配置中心 (Config Server) 获取最新配置

  5. 全部客户端均获取到最新的配置

存在以下问题:

  破坏了微服务职责的单一性,因为微服务本身就是一个业务模块,它本不应该承担配置刷新的职责。

  破坏了微服务各个节点的对等性,例如有 A、B、C 三个订单模块集群,如果 B、C 服务没有更新功能,只有 A 服务更新功能的话。既增加了额外的负担,又破坏了平衡性,会导致整个集群会产生分裂。

  有一定的局限性。例如微服务正在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改。

第二种方式:利用消息总线触发一个服务端Config Server的/bus/refresh端点,而刷新所有客户端的配置。

 

  1. 提交配置触发 POST 请求给配置中心 (Config Server) 的 /bus/refresh 接口

  2. 配置中心 (Config Server) 接收到请求并发送给 Bus 消息总线

  3. Bus 消息总线接收到消息并通知给其他连接的总线的客户端

  4. 其他客户端接收到通知,请求配置中心 (Config Server) 获取最新配置

  5. 全部客户端获取到最新的配置

 

三、Bus实现动态刷新配置

  Spring Cloud Bus 是对上一讲 Config分布式统一配置中心 的扩充,好处说明它是广播型的,自动版的动态刷新。是 Spring Cloud Config 的绝配,要用就一起使用,Bus 与 Config 使用可以实现配置的动态刷新功能。

我们通过使用config-server配置中心来通知config-client与config-rabbitmq两个客户端:

为Config Server添加消息总线支持

1)补充build.gradle项目依赖

修改config-server模块并添加消息总线rabbitmq依赖

compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-bus-amqp'

2)补充application.yaml配置文件

添加消息总线的支持后需要暴露bus刷新配置的端点和rabbitmq相关的配置信息

server:
  port: 7001
spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          uri: https://github.com/wessonshin/config-server.git
          username: your git username
          password: your git password
          clone-on-start: true
          search-paths:
            - config-server
  #RabbitMQ相关配置
  rabbitmq:
    host: localhost #RabbitMQ的主机地址
    port: 5672 #RabbitMQ的端口号
    username: guest #登录到RabbitMQ用户名
    password: guest #登录到RabbitMQ密码
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
management:
  endpoints:
    web:
      exposure:
        include: 'bus-refresh'
View Code

为Config Client添加消息总线支持

参考上一讲config-client客户端,在创建一个config-rabbitmq工程,代码和config-client相同。

3)补充build.gradle项目依赖

修改config-client和config-rabbitmq两个模块并添加actuator监控与消息总线rabbitmq依赖

compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'

compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-bus-amqp'

4)补充application.yaml配置文件

Config客户端只需要新添加rabbitmq相关配置信息就OK了,其它不变

server:
  port: 7071
spring:
  application:
    name: config-client
  cloud:
    config:
      label: master
      name: config-server
      profile: dev
      uri: http://localhost:7001
  #RabbitMQ相关配置
  rabbitmq:
    host: localhost #RabbitMQ的主机地址
    port: 5672 #RabbitMQ的端口号
    username: guest #登录到RabbitMQ用户名
    password: guest #登录到RabbitMQ密码
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
management:
  endpoints:
    web:
      exposure:
        include: 'refresh'
View Code

5)测试

Step1:运行 eureka-server 启动类,端口为8761

Step2:运行 config-server 启动类,端口为7001

Step3:分别运行两个Config客户端,config-client与config-rabbitmq启动类,端口分别为7071与7072

Step4:先访问http://localhost:8761/,注册到的服务如下图:

Step5:我们继续修改远程 GitHub 仓库版本号为:

Step6:此处刷新的是配置中心服务端,而不是客户端。需要发送Post请求,将windows10的cmd命令窗口打开,输入命令如下:

  • curl -X POST "http://localhost:7001/actuator/bus-refresh"

Step7:使用配置中心访问远程 GitHub 仓库还是能够直接获取到更新版本号:

Step8:接着通过两个Config客户端访问,同样也能够从远程 GitHub 仓库直接获取到更新版本号:

 此时仍然不用重启服务,同时客户端可跟着一起更新版本。达到了一次修改,广播通知,处处生效的效果。

posted @ 2020-03-21 22:56  wessonshin  阅读(244)  评论(0编辑  收藏  举报