上一章节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 实现配置的动态刷新需要以下步骤:
  1. Git 仓库中的配置发生改变后,运维人员向 Config 服务端发送一个 POST 请求,请求路径为actuator/busrefresh
  2. Config 服务端接收到请求后,会将该请求转发给服务总线 Spring Cloud Bus。
  3. Spring Cloud Bus 接到消息后,会通知给所有 Config 客户端。
  4. Config 客户端接收到通知,请求 Config 服务端拉取最新配置。
  5. 所有 Config 客户端都获取到最新的配置。

画板

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

1. 修改spring-cloud-config-center-8006

  1. config服务端spring-cloud-config-center-8006添加以下依赖
  • Spring Boot actuator 监控模块
  • Spring Cloud Bus 的依赖
  1. <!--添加消息总线(Bus)对 RabbitMQ 的支持-->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-bus-amqp</artifactId>
  5. </dependency>
  6. <!--添加Spring Boot actuator 监控模块的依赖-->
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-actuator</artifactId>
  10. </dependency>
  1. 修改配置文件
  1. # RabbitMQ 相关配置,15672 是web 管理界面的端口,5672 是 MQ 的访问端口
  2. spring:
  3. rabbitmq:
  4. host: 127.0.0.1
  5. port: 5672
  6. username: guest
  7. password: guest
  8. # Spring Boot 2.50对 actuator 监控屏蔽了大多数的节点,只暴露了 heath 节点,本段配置(*)就是为了开启所有的节点。也可以单独暴露指定节点(include: "bus-refresh")
  9. management:
  10. endpoints:
  11. web:
  12. exposure:
  13. include: "*" # * 在yaml 文件属于关键字

2. 修改 spring-cloud-config-client-8007

  1. 添加核心依赖
  1. <!--SpringCloud2020及以后的版本默认不启用 bootstrap 配置,我们需要在pom里面显式地引入:-->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-bootstrap</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-actuator</artifactId>
  9. </dependency>
  10. <!--添加消息总线(Bus)对 RabbitMQ 的支持-->
  11. <dependency>
  12. <groupId>org.springframework.cloud</groupId>
  13. <artifactId>spring-cloud-starter-bus-amqp</artifactId>
  14. </dependency>
  1. 添加配置文件
  1. # RabbitMQ 相关配置,15672 是web 管理界面的端口,5672 是 MQ 的访问端口
  2. spring:
  3. rabbitmq:
  4. host: 127.0.0.1
  5. port: 5672
  6. username: guest
  7. password: guest
  8. # Spring Boot 2.50对 actuator 监控屏蔽了大多数的节点,只暴露了 heath 节点,本段配置(*)就是为了开启所有的节点。也可以单独暴露指定节点(include: "bus-refresh")
  9. management:
  10. endpoints:
  11. web:
  12. exposure:
  13. include: "*" # * 在yaml 文件属于关键字

3. 创建spring-cloud-config-client-bus-8008

要演示消息广播的这种效果,所以我们再增加一个客户端服务 8008,其本质和 8007config客户端 基本一样。这里的作用主要是为了展示是否可以全局刷新,没什么特殊知识。

4. 测试

依次启动9001注册中心,8006config服务端,6007config客户端和8008config客户端。

访问config两个客户端查看目前获取的最新配置如下:

修改配置文件 config-dev.yml中的 config.version 修改为 4.0,配置如下

  1. config:
  2. info: spring-cloud-config-center-8006-dev
  3. branch: master
  4. name: config-dev.yml
  5. version: 4.0

打开命令行窗口,使用以下命令向spring-cloud-config-center-8006(Config Server)发送一个 POST 请求,刷新配置。

  1. curl -X POST "http://localhost:8006/actuator/busrefresh"

请求OK后,在次请求8007和8008客户端会发现全部都刷新了。

Spring Cloud Bus - 图2

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"
  1. 修改config-dev.yml中的 config.version 修改为 5.0,配置如下
  1. config:
  2. info: spring-cloud-config-center-8006-dev
  3. branch: master
  4. name: config-dev.yml
  5. version: 5.0
  1. 在黑窗口中使用以下命令更细指定的服务刷新配置如下:
  1. $ curl -X POST "http://localhost:8006/actuator/busrefresh/spring-cloud-config-client-bus-8008:8008"
  1. 浏览器分别访问8007、8008两个服务查看是否刷新,可以看出指定的服务已经刷新到最新配置,尔8007还是老配置

Spring Cloud Bus - 图3