1. 概述
本文将深入探讨 Spring Cloud Bus 项目。Spring Cloud Bus 通过轻量级消息代理连接分布式系统节点,主要用于广播配置变更或其他管理指令。可以将其视为分布式版的 Actuator。
该项目默认使用 AMQP 代理作为传输层,但也可替换为 Apache Kafka 或 Redis(目前仅支持这三种传输方式)。本教程将以 RabbitMQ 为主要传输层进行演示,请确保已提前启动 RabbitMQ 服务。
2. 前置准备
开始前建议先完成《Spring Cloud Configuration 快速入门》教程。我们将基于现有的配置服务器和客户端进行扩展,实现配置变更的自动通知机制。
2.1. RabbitMQ 安装
推荐使用 Docker 方式部署 RabbitMQ,操作非常简单。首先确保已安装 Docker,然后执行以下命令:
docker pull rabbitmq:3-management
此命令会拉取预装管理插件的 RabbitMQ 镜像。接着启动容器:
docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management
启动后访问 http://localhost:15672 可进入管理控制台(默认账号密码均为 guest
)。同时 RabbitMQ 会在 5672 端口监听消息。
3. 为配置客户端添加 Actuator
假设已有配置服务器和客户端在运行。目前每次配置变更后都需要重启客户端——这显然不够优雅。
先停止客户端,在 ConfigClient
控制器类上添加 @RefreshScope
注解:
@SpringBootApplication
@RestController
@RefreshScope
public class SpringCloudConfigClientApplication {
// 代码实现...
}
然后更新 pom.xml
添加 Actuator 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
最新版本可查看 Maven 中央仓库
默认情况下 Actuator 的敏感接口(包括 /refresh
)是受保护的。为简化演示,在 application.yml
中关闭安全验证:
management:
security:
enabled: false
⚠️ 注意:Spring Boot 2 后 Actuator 接口默认不暴露,需额外配置:
management:
endpoints:
web:
exposure:
include: "*"
重启客户端后,在 GitHub 仓库中将 user.role
从 Developer
改为 Programmer
。此时配置服务器会立即更新,但客户端不会。手动触发刷新只需向 /actuator/refresh
发送空 POST 请求:
$> curl -X POST http://localhost:8080/actuator/refresh
返回的 JSON 会显示更新的属性:
[
"user.role"
]
验证更新结果:
$> curl http://localhost:8080/whoami/Mr_Pink
Hello Mr_Pink! You are a(n) Programmer and your password is 'd3v3L'.
✅ 成功通过 /refresh
接口实现无重启配置更新。
4. Spring Cloud Bus 集成
虽然 Actuator 能刷新单个客户端,但在云环境中逐个触发显然不现实。Spring Cloud Bus 正是解决这个问题的利器。
4.1. 客户端改造
让客户端订阅 RabbitMQ 消息队列,添加依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
<version>4.1.1</version>
</dependency>
最新版本查看 Maven 中央仓库
在 application.yml
中配置 RabbitMQ 并启用 Bus:
---
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
cloud:
bus:
enabled: true
refresh:
enabled: true
⚠️ 生产环境务必修改默认账号密码!
改造后客户端新增 /bus-refresh
接口,调用该接口会:
- 从配置服务器获取最新配置,更新
@RefreshScope
标注的 Bean - 向 AMQP 交换机发送刷新事件消息
- 所有订阅节点同步更新配置
4.2. 服务器改造
在配置服务器添加两个依赖实现自动化:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-monitor</artifactId>
<version>4.1.1</version>
</dependency>
最新版本查看 Maven 中央仓库
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
<version>4.1.1</version>
</dependency>
最新版本查看 Maven 中央仓库
在 application.properties
中添加 RabbitMQ 配置:
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
4.3. GitHub Webhook 配置
现在配置服务器已能通过 RabbitMQ 广播变更事件,但如何感知配置文件修改?需要配置 GitHub Webhook:
- 进入配置仓库的 GitHub 页面
- 选择 Settings → Webhooks
- 点击 Add webhook
- Payload URL 填写配置服务器的
/monitor
接口地址:http://root:s3cr3t@REMOTE_IP:8888/monitor
- Content type 选择
application/json
- Secret 留空
- 点击 Add webhook 完成配置
5. 功能测试
确保所有服务运行中。当前客户端显示:
$> curl http://localhost:8080/whoami/Mr_Pink
Hello Mr_Pink! You are a(n) Programmer and your password is 'd3v3L'.
现在修改 GitHub 仓库中的配置文件,将 user.role
改回 Developer
:
user.role=Developer
无需手动刷新,立即检查客户端:
$> curl http://localhost:8080/whoami/Mr_Pink
Hello Mr_Pink! You are a(n) Developer and your password is 'd3v3L'.
✅ 客户端自动同步更新!在 GitHub Webhook 的 Recent Deliveries 中可查看发送给配置服务器的 JSON 数据。服务器日志会显示:
o.s.cloud.bus.event.RefreshListener: Received remote refresh request. Keys refreshed []
6. 总结
本文基于现有 Spring Cloud 配置服务器和客户端:
- 通过 Actuator 实现手动配置刷新
- 集成 Spring Cloud Bus 实现配置变更广播
- 配合 GitHub Webhook 实现全自动更新流程
完整代码示例可在 GitHub 仓库 获取。踩坑提示:生产环境务必注意 RabbitMQ 安全配置,避免使用默认凭证!