Bus 消息总线
概述
分布式自动刷新配置功能
Spring Cloud Bus 配合 Spring Cloud Config使用可以实现配置的动态刷新
Bus支持两种消息代理:RabbitMQ和Kafka
Spring Cloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架,它整合了Java的事件处理机制和消息中间件的功能
SpringCloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道
总线概念
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来,由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线
在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息
基本原理
ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置
RabbitMQ 环境配置
Erlang 安装
RabbitMQ官方推荐下载地址:https://www.erlang-solutions.com/resources/download.html
RabbitMQ 安装
下载地址:https://www.rabbitmq.com/install-windows.html#installer
安装完成在任务管理器中的服务可以看到
配置RabbitMQ
-
进入RabbitMQ安装目录下的 sbin 目录
-
安装RabbitMQ-Plugins,启动管理功能
在当前目录下启动 cmd
rabbitmq-plugins enable rabbitmq_management
服务启动后,访问 http://localhost:15672(默认地址)
默认账号:guest,默认密码:guest
全局广播
演示广播效果,增加复杂度,再创建一个客户端,现在拥有两个客户端,一个服务端
设计思想
-
第一种:利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,而刷新所有客户端的配置
-
第二种:利用消息总线触发一个客户端/bus/refresh,而刷新所有客户端的配置
对比两种设计思想,第一种更合适
第二种不适合的原因:
- 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责
- 破坏了微服务各节点的对等性
- 有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改
服务端
- 增加 pom 依赖
<!-- 消息总线 RabbitMQ 支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 配置 yml 文件
spring:
application:
name: Config-center
# rabbitmq 相关配置
rabbitmq:
host: localhost
port: 5672
username: guest
password: guset
# rabbitmq 相关配置,暴露 bus 刷新配置的端点
management:
endpoints:
# 暴露 bus 刷新配置的端点
web:
exposure:
include: 'bus-refresh'
客户端
- 增加 pom 依赖
<!-- 消息总线 RabbitMQ 支持 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 配置 yml 文件
spring:
application:
name: Config-client
# rabbitmq 相关配置
rabbitmq:
host: localhost
port: 5672
username: guest
password: guset
修改github上application的内容,发送一次 POST 请求,实现全局修改,直接在 服务端 发送请求,即可达到全局修改
curl -X POST "http://localhost:3344/actuator/bus-refresh"
定点通知
指定某些实例生效而不是全部
http://localhost:配置中心端口号/actuator/bus-refresh/{destination}
/bus/refresh请求不再发送到具体的服务实例上,而是发给 configserver 通过 destination 参数类指定需要更新配置的服务或实例
我们这里以刷新运行在3355端口上的config-client为例,只通知3355,不通知3366
http://localhost:配置中心端口号/actuator/bus-refresh/服务名:端口号
curl -X POST http://localhost:3344/actuator/bus-refresh/Config-client:3355