文章目录
一、Spring Cloud Bus是什么?
Spring Cloud Bus 是用来将分布式系统的节点与轻量级消息系统链接起来的框架, 它整合了 JAVA 的时间处理机制和消息中间件的功能
Spring Cloud Bus 目前仅支持 Rabbit Mq 和 Kafka
SpringCloud Bus 能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改,事件推送等,也可以当做微服务间的通信通道
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个供用的消息主题,并让系统中所有的微服务实例都连接上来,由于该主题中产生的消息会被所有的实例监听和消费,所以称他为消息总线,在总线的各个实例上,都可以方便广播一些需要让其他连接在该主题上的实例都知道的消息。
ConfigClient 实例都监听MQ 中的同一个 topic (默认是SpringCloudBus), 当一个服务刷新数据的时候,他会吧这个信息放入到Topic中,这样其他监听同一个Topic 的服务都能得到通知,然后去更新自身的配置。
二、使用步骤
1.1 RabbitMQ安装
省略。。。
1.2 创建sgg-config-client3366
模块
导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置 yml 文件。
server:
port: 3366
spring:
application:
name: config-service
cloud:
config:
profile: dev
uri: http://localhost:3344
label: master
配置 config 配置中心的配置文件
eureka:
instance:
instance-id: config-service-${server.port}
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
management:
endpoints:
web:
exposure:
include: "*"
payment:
version: 1.0
修改了config.version = 1.0
创建ConfigController.java
@RestController
@Slf4j
@RequestMapping(value = "/config")
@RefreshScope
public class ConfigController {
@Value("${server.port}")
private Integer port;
@Value("${eureka.instance.instance-id}")
private String instanceId;
@Value("${eureka.client.service-url.defaultZone}")
private String defaultZone;
@Value("${payment.version}")
private String version;
@GetMapping(value = "/getConfigInfo")
public String getConfigInfo(){
JSONObject configInfo = new JSONObject();
configInfo.put("port", port);
configInfo.put("instanceId", instanceId);
configInfo.put("defaultZone", defaultZone);
configInfo.put("version", version);
return configInfo.toString();
}
}
1.3 设计思想。
刚开始介绍的时候有两张图。第一张图是利用消息 总线触发一个客户端 /bus/refresh , 从而刷新所有的客户端配置
第二张图,利用消息总线触发一个服务端 ConfigServer的 /bus/refresh 端点,而刷新所有的客户端的配置
显然图二更适合。原因如下:
- 图一打破了微服务的职责单一性,因为微服务本身是业务模块,不应该承担配置刷新的职责
- 破坏了微服务各节点的对等性
- 有一定的局限性,例如 微服务迁移时,它的网络地址经常发生变化。 如果此时想要做到自动刷新。那就会增加更多的的修改
1.4 给项目模块sgg-config-center3344
添加消息总线依赖
<!-- 添加消息总线-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
配置 sgg-config-center3344
的yml 文件
server:
port: 3344
spring:
application:
name: sgg-config-center-service
cloud:
config:
server:
git:
uri: https://gitee.com/gssnb/springcloud-config.git
username: 15152268067
password: 584521..gao
search-paths: / # 读取文件的跟地址
default-label: master # 默认使用的分支
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
eureka:
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
instance:
instance-id: sgg-config-center-service-${server.port}
# 配置rabbitmq 相关配置。 暴露bus 刷新配置的端点
management:
endpoints: # 暴露bus 刷新配置的端点
web:
exposure:
include: 'bus-refresh'
配置 3355 3366 服务
同样修改,不同的是不要忘记修改 config 配置中心的 rabbitmq 配置哦,记得删除 config 配置中心的端口号。
3355 服务
spring:
application:
name: payment-service
cloud:
config:
uri: http://localhost:3344
label: master
profile: dev
server:
port: 3355
3366 服务
spring:
application:
name: payment-service
cloud:
config:
profile: dev
uri: http://localhost:3344
label: master
server:
port: 3366
顺序 启动 7001, 7002, 3344, 3355, 3366 服务
先查看我们的 payment-service-dev.yml 文件中 version 的值
version = 3.0 。 访问我们的 3355 和 3366 提供的接口
也是 3.0 。 这时候。我们去修改 git 上面的配置文件
更新为 4.0 上传到 远程仓库
访问 3344 接口 。 version已经更新到 4.0 了。
访问 3355 和 3366 还是 3.0 因为这个时候 我们需要手动 refresh 一下 。 才可以更新我们的配置内容 。 refresh 需要调用 config Server. 然后 config server 在通过消息队列广播给其他的微服务。 进行自动更新
通过 curl 命令进行 post 请求 http://localhost:3344/actuator/bus-refresh
Attempting to connect to: [127.0.0.1:5672]
2020-09-13 21:54:20.853 INFO 15848 --- [JSEmHfbZuTTtA-1] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory.publisher#ee4c20d:0/SimpleConnection@5695bd14 [delegate=amqp://guest@127.0.0.1:5672/, localPort= 53908]
2020-09-13 21:54:20.853 INFO 15848 --- [JSEmHfbZuTTtA-1] o.s.amqp.rabbit.core.RabbitAdmin : Auto-declaring a non-durable, auto-delete, or exclusive Queue (springCloudBus.anonymous.6g7dgutPTJSEmHfbZuTTtA) durable:false, auto-delete:true, exclusive:true. It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.
3355, 3366 的 控制台命令会收到rabbit mq 的广播 日志打印。
访问详情接口。 会发现我们的 version 已经 更新成了 4.0
采坑总结: 端点设置如果是 * 记得使用 双引号。 如果是 bus-refresh 记得使用 ‘’ 单引号。 说多了都是泪。
这里查看我们的 RabbitMQ 也能看到 SpringCloud BUS 的 队列 三个。 其实就是ConfigServer 通过 topic 订阅通知来完成的。 如果想要完成全自动的。 可以去了解一下 Git 的 WebHook 。
1.5 Bus 动态刷新定点通知
如果我们微服务不想通知全部,只想定点通知。 比如说我们的 3355, 和3366 。 但是我们只想通知 3355 不想通知 3366
http://localhost:3344/actuator/bus-refresh/{spring.application.name:server.port}
意思就是后面跟上 微服务名称:端口号
修改 version=5.0
通过 CURL命令访问 bus-refresh
接口
此时分别访问 3355 服务 和 3366 服务试试看
定点刷新就这样完成了、 ~~~~
总结 感谢B站尚硅谷的老师们~~~
参考文章 : 芋道源码