SpringCloud(Greenwich版)Bus消息总线
推荐以下稳定版本号:
Spring Boot: 2.1.9.RELEASE
是什么?
Spring Cloud Bus 使用轻量级的消息代理(目前只支持两种,RabbitMQ 和 Kafka)连接分布式系统的节点,这样就可以广播传播状态的更改(例如配置的更新)或者其他的管理指令。可将 Spring Cloud Bus 想象成一个分布式 Spring Boot Actuator,也可以当做微服务间的通信通道。
为什么被称为消息总线?
在微服务系统架构中,通常会使用轻量级的消息代理来构建一个共用的消息主题(订阅某学校的微信公众号 topic),并让系统中所有微服务实例(可以理解为所有学生 micro-service)都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称之为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。
基本原理:
Config Client 实例都监听 MQ 中同一个主题 (topic),当一个服务刷新数据的时候,它会把这个信息放入主题 (topic) 中,这样其它监听同一个主题 (topic) 的服务就能够得到通知,然后去更新自身配置。
登录RabbitMQ Web页面后,在我们的 Exchanges (RabbitMQ交换机) 中,会有一个默认的名称:springCloudBus
-
提交配置出发 POST 请求调用客户端A (Config Client) 的 /bus/refresh 接口
-
客户端A (Config Client) 收到请求从配置中心 (Config Server) 更新配置并且发送给 Bus 消息总线
-
Bus 消息总线接收消息并通知给其他连线在总线上的客户端,所有总线上的客户端均能接收到消息
-
其他客户端接收到消息,请求配置中心 (Config Server) 获取最新配置
-
全部客户端均获取到最新的配置
存在以下问题:
破坏了微服务职责的单一性,因为微服务本身就是一个业务模块,它本不应该承担配置刷新的职责。
破坏了微服务各个节点的对等性,例如有 A、B、C 三个订单模块集群,如果 B、C 服务没有更新功能,只有 A 服务更新功能的话。既增加了额外的负担,又破坏了平衡性,会导致整个集群会产生分裂。
有一定的局限性。例如微服务正在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改。
-
提交配置触发 POST 请求给配置中心 (Config Server) 的 /bus/refresh 接口
-
配置中心 (Config Server) 接收到请求并发送给 Bus 消息总线
-
Bus 消息总线接收到消息并通知给其他连接的总线的客户端
-
其他客户端接收到通知,请求配置中心 (Config Server) 获取最新配置
-
全部客户端获取到最新的配置
三、Bus实现动态刷新配置
为Config Server添加消息总线支持
1)补充build.gradle项目依赖
修改config-server模块并添加消息总线rabbitmq依赖
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-bus-amqp'
2)补充application.yaml配置文件
添加消息总线的支持后需要暴露bus刷新配置的端点和rabbitmq相关的配置信息
server:
port: 7001
spring:
application:
name: config-server
cloud:
config:
server:
git:
uri: https://github.com/wessonshin/config-server.git
username: your git username
password: your git password
clone-on-start: true
search-paths:
- config-server
#RabbitMQ相关配置
rabbitmq:
host: localhost #RabbitMQ的主机地址
port: 5672 #RabbitMQ的端口号
username: guest #登录到RabbitMQ用户名
password: guest #登录到RabbitMQ密码
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
为Config Client添加消息总线支持
参考上一讲config-client客户端,在创建一个config-rabbitmq工程,代码和config-client相同。
修改config-client和config-rabbitmq两个模块并添加actuator监控与消息总线rabbitmq依赖
compile group: 'org.springframework.boot', name: 'spring-boot-starter-actuator'
compile group: 'org.springframework.cloud', name: 'spring-cloud-starter-bus-amqp'
4)补充application.yaml配置文件
Config客户端只需要新添加rabbitmq相关配置信息就OK了,其它不变
server:
port: 7071
spring:
application:
name: config-client
cloud:
config:
label: master
name: config-server
profile: dev
uri: http://localhost:7001
#RabbitMQ相关配置
rabbitmq:
host: localhost #RabbitMQ的主机地址
port: 5672 #RabbitMQ的端口号
username: guest #登录到RabbitMQ用户名
password: guest #登录到RabbitMQ密码
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
management:
endpoints:
web:
exposure:
include: 'refresh'
5)测试
Step1:运行 eureka-server 启动类,端口为8761
Step2:运行 config-server 启动类,端口为7001
Step3:分别运行两个Config客户端,config-client与config-rabbitmq启动类,端口分别为7071与7072
Step4:先访问http://localhost:8761/,注册到的服务如下图:
Step6:此处刷新的是配置中心服务端,而不是客户端。需要发送Post请求,将windows10的cmd命令窗口打开,输入命令如下:
-
curl -X POST "http://localhost:7001/actuator/bus-refresh"
Step7:
Step8: