1. Bus

1. Bus简介

1. 上—讲解的加深和扩充

使用Spring Cloud Bus 配合Spring Cloud Config使用可以实现分布式配置的动态刷新功能

2. 概念

八、服务总线 - 图1

ps:如图示,Post刷新信息传递到其中一台客户端,再由Bus传递到其他的客户端

Spring Cloud Bus是用来将分布式系统的节点轻量级消息系统链接起来的框架,它整合了Java的事件处理机制消息中间件的功能。Spring Clud Bus目前支持RabbitMQKafka

3. 作用

Spring Cloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道
八、服务总线 - 图2

如图示:Post刷新信息直接发送到配置服务中心,由配置服务中心传递到其他所有的客户端,从而进行刷新

4. 为何被称为总线

什么是总线
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息

基本原理
ConfigClient实例都监听MQ中同一个Exchange(默认是Spring Cloud Bus)当一个服务刷新数据的时候,它会把这个信息放入到Exchange队列中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置

2. Bus——RabbitMQ环境配置

Docker启动RabbitMQ
RabbitMQ详解
访问可视化页面
image.png

3. Bus动态刷新全局广播的设计思想和选型

必须先具备良好的RabbitMQ环境先,演示广播效果,增加复杂度,再以3355为模板再制作一个3366
创建流程与之类似,注意更换端口号

设计思想一:利用消息总线触发一个客户端/bus/refresh,而刷新所有客户端的配置

八、服务总线 - 图4

设计思想二:利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,而刷新所有客户端的配置

八、服务总线 - 图5

架构选型

图二的架构显然更加适合,图—不适合的原因如下:

  • 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责。
  • 破坏了微服务各节点的对等性。
  • 有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改

4. Bus动态刷新全局广播配置实现

1. 给予配置中心、配置客户端服务消息总线支持

pom.xml中添加RabbitMQ支持的消息总线依赖

  1. <!--添加消息总线RabbitNQ支持-->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-bus-amap</artifactId>
  5. </dependency>

application.yaml、bootstrap.yaml中添加RabbitMQ相关配置

spring:
  #RabbitMQ配置
  rabbitmq:
    username: gmf
    password: 2373271519...
    virtual-host: /
    port: 5672
    host: 192.168.43.11

#暴露bus动态刷新端点
management:
  endpoints:
    web:
      exposure:
        include: "bus-refresh"

2. 测试

启动以下服务

  • EurekaMain7001
  • ConfigcenterMain3344
  • ConfigclientMain3355
  • ConfigclicntMain3366

模拟运维工程师修改配置文件Git到远程库
image.png
运维工程师向配置中心发送Post Bus Refresh请求
image.png
浏览器访问3355、3366查看配置项是否更改
image.png
image.png
结论:发现配置服务项都已修改,真正做到了—次修改,广播通知,处处生效

5. Bus动态刷新定点通知

如果不想全部通知,只想定点通知单个微服务(指定具体某一个实例生效而不是全部

  • 只通知3355
  • 不通知3366

http://配置中心host:port/actuator/bus-refresh/{destination}:/bus/refresh请求不再发送到具体的服务实例上,而是发给config server通过destination参数类指定需要更新配置的服务或实例

案例

在GitHub/Gitee中修改配置文件
image.png

我们这里以刷新运行在3355端口上的config-client(配置文件中设定的应用名称)为例,只通知3355,不通知3366
image.png

浏览器访问:http://localhost:3355/configInfo 显示内容已修改
image.png

浏览器再测试访问:http://localhost:3366/configInfo 配置仍未修改
image.png

总结

八、服务总线 - 图14