1. 消息总线概述 1.1 分布式配置的动态刷新问题
Linux运维修改Github上的配置文件内容做调整
刷新3344,发现ConfigServer配置中心立刻响应
刷新3355,发现ConfigClient客户端没有任何响应
3355没有变化除非自己重启或者重新加载
难道每次运维修改配置文件,客户端都需要重启?
1.2 消息总线加强ConfigSpringCloud Bus配合SpringCloud Config使用可以实现配置的动态刷新。
用SpringCloud Config时,我们可以实现配置信息手动的动态刷新,也就是远端配置信息发生改变后,需要告诉服务端配置信息发生变化后,服务端才会更新配置信息,而现在我们想要实现分布式自动刷新配置信息功能,这就需要我们使用SpringCloud Bus消息总线配合SpringCloud Config实现配置信息的动态刷新。
SpringCloud Bus是用来将分布式系统的节点与轻量级消息系统连接起来的框架,它整合了Java的事件处理机制和消息中间件的功能,SpringCloud Bus目前支持两种消息代理:RabbitMQ和Kafka。
SpringCloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等, 也可以当做微服务间的通信通道。
1.2 为什么被称为总线在微服务架构的系统中,通常会 使用轻量级的消息代理 来构建一个 共用的消息主题,并让系统中所有微服务实例都连接上来,由于 该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。
基本原理:SpringCloud Config客户端的实例都监听消息队列中的同一个主题(topic)(默认是SpringCloud Bus),当一个服务器刷新数据的时候,它会把这个信息放入到主题中,这样其他监听了同一主题的服务就能得到通知,然后去更新自身的配置。
1.3 安装RabbitMQ直接使用docker-compose安装吧!
访问地址看是否安装成功::15672,输入账号并登录,默认guest/guest
2. SpringCloud Bus动态刷新全局广播在学习SpringCloud Config的时候我们已经建立了服务cloud-config-client-3355作为Config的客户端,这里为了演示广播效果,我们增加复杂度,再以3355为模板再制作另一个Config的客户端3366,建立Module:cloud-config-client-3366,其结构和cloud-config-client-3355类似,修改下服务端口号即可。
修改以下3355/3366的controller,用于区分
@RestController @RefreshScope public class ConfigClientController { @Value("${server.port}") private String serverPort; @Value("${server.info}") private String configInfo; @GetMapping("/configInfo") public String getConfigInfo() { return "serverPort:" + serverPort + "\t configInfo:" + configInfo; } } 2.1 消息总线的两种设计思想方案一
利用消息总线 触发一个客户端/bus/refresh端点,而后刷新所有客户端的配置:
方案二
利用消息总线 触发一个服务端ConfigServer的/bus/refresh端点,而后刷新所有客户端的配置:
两种方案对比
明显第二种架构更加合适,第一种架构不合适的原因主要有:
打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责
破坏了微服务各节点的对等性
有一定的局限性,比如在微服务迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改
所以虽然从技术上两种方案都可以实现,但是无疑在技术选型上我们应该选择第二种方案。
2.2 3344服务端添加消息总线支持在其POM文件中添加使用RabbitMQ实现消息总线的依赖:
<!--添加消息总线RabbitMQ支持--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>然后在其yml配置文件中添加RabbitMQ的相关配置,暴露SpringCloud Bus刷新配置的端点
# RabbitMQ相关配置 spring: rabbitmq: host: mpolaris.top port: 5672 username: admin password: 1234321 # 暴露总线刷新配置的端点 management: endpoints: web: exposure: include: 'bus-refresh' 2.3 3355/3366客户端添加消息总线支持