上一章节config配置学习中其实是有个问题的。假如多个config客户端我们每次更新配置都要post一次客户端吗?这显然是不合理的,能不能进行广播式通知呢,一次通知,处处生效,亦或者大范围自动刷新。我们本章节学习通过Bus这个组件实现广播式的动态刷新。
Spring Cloud Bus 又被称为消息总线,它能够通过轻量级的消息代理(使用RabbitMQ)将微服务架构中的各个服务连接起来,实现广播状态更改、事件推送等功能,还可以实现微服务之间的通信功能。
Spring Cloud Bus 的基本原理:Spring Cloud Bus 会使用一个轻量级的消息代理来构建一个公共的消息主题 Topic(默认为“springCloudBus”),这个 Topic 中的消息会被所有服务实例监听和消费。当其中的一个服务刷新数据时,Spring Cloud Bus 会把信息保存到 Topic 中,这样监听这个 Topic 的服务就收到消息并自动消费。 Spring Cloud Bus 动态刷新配置的原理:当 Git 仓库中的配置发生了改变,我们只需要向某一个服务(既可以是 Config 服务端,也可以是 Config 客户端)发送一个 POST 请求,Spring Cloud Bus 就可以通过消息代理通知其他服务重新拉取最新配置,以实现配置的动态刷新。 Spring Cloud Bus 实现配置的动态刷新需要以下步骤:- Git 仓库中的配置发生改变后,运维人员向 Config 服务端发送一个 POST 请求,请求路径为
actuator/busrefresh
。 - Config 服务端接收到请求后,会将该请求转发给服务总线 Spring Cloud Bus。
- Spring Cloud Bus 接到消息后,会通知给所有 Config 客户端。
- Config 客户端接收到通知,请求 Config 服务端拉取最新配置。
- 所有 Config 客户端都获取到最新的配置。
Bus 动态刷新全局广播配置实现
1. 修改spring-cloud-config-center-8006
- config服务端
spring-cloud-config-center-8006
添加以下依赖
- Spring Boot actuator 监控模块
- Spring Cloud Bus 的依赖
<!--添加消息总线(Bus)对 RabbitMQ 的支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!--添加Spring Boot actuator 监控模块的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 修改配置文件
# RabbitMQ 相关配置,15672 是web 管理界面的端口,5672 是 MQ 的访问端口
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
# Spring Boot 2.50对 actuator 监控屏蔽了大多数的节点,只暴露了 heath 节点,本段配置(*)就是为了开启所有的节点。也可以单独暴露指定节点(include: "bus-refresh")
management:
endpoints:
web:
exposure:
include: "*" # * 在yaml 文件属于关键字
2. 修改 spring-cloud-config-client-8007
- 添加核心依赖
<!--SpringCloud2020及以后的版本默认不启用 bootstrap 配置,我们需要在pom里面显式地引入:-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--添加消息总线(Bus)对 RabbitMQ 的支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
- 添加配置文件
# RabbitMQ 相关配置,15672 是web 管理界面的端口,5672 是 MQ 的访问端口
spring:
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
# Spring Boot 2.50对 actuator 监控屏蔽了大多数的节点,只暴露了 heath 节点,本段配置(*)就是为了开启所有的节点。也可以单独暴露指定节点(include: "bus-refresh")
management:
endpoints:
web:
exposure:
include: "*" # * 在yaml 文件属于关键字
3. 创建spring-cloud-config-client-bus-8008
要演示消息广播的这种效果,所以我们再增加一个客户端服务 8008
,其本质和 8007
config客户端 基本一样。这里的作用主要是为了展示是否可以全局刷新,没什么特殊知识。
4. 测试
依次启动9001注册中心,8006config服务端,6007config客户端和8008config客户端。
访问config两个客户端查看目前获取的最新配置如下:
修改配置文件 config-dev.yml
中的 config.version
修改为 4.0
,配置如下
config:
info: spring-cloud-config-center-8006-dev
branch: master
name: config-dev.yml
version: 4.0
打开命令行窗口,使用以下命令向spring-cloud-config-center-8006
(Config Server)发送一个 POST 请求,刷新配置。
curl -X POST "http://localhost:8006/actuator/busrefresh"
请求OK后,在次请求8007和8008客户端会发现全部都刷新了。
Bus动态刷新定点通知
如果只想通知其中某个服务,例如只想通知 8008,但是不想通知 8007,如何实现呢,如下操作:
写法:config服务端地址 + 微服务名称:端口号
- 写法:
curl -X POST "http://localhost:8006/actuator/busrefresh/你的微服务名称:端口号"
- 例如:
curl -X POST "http://localhost:8006/actuator/busrefresh/spring-cloud-config-client-bus-8008:8008"
- 修改
config-dev.yml
中的config.version
修改为5.0
,配置如下
config:
info: spring-cloud-config-center-8006-dev
branch: master
name: config-dev.yml
version: 5.0
- 在黑窗口中使用以下命令更细指定的服务刷新配置如下:
$ curl -X POST "http://localhost:8006/actuator/busrefresh/spring-cloud-config-client-bus-8008:8008"
- 浏览器分别访问8007、8008两个服务查看是否刷新,可以看出指定的服务已经刷新到最新配置,尔8007还是老配置