SpringCloud Hoxton——Bus服务消息总线
Posted 张起灵-小哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud Hoxton——Bus服务消息总线相关的知识,希望对你有一定的参考价值。
1.开篇
上一篇文章说到SpringCloud中的Config服务配置,最后遗留下了一个问题:我们可以使用curl -X POST命令为配置客户端发送请求,使得客户端此时实现了动态刷新,能够拿到最新的配置数据;倘若有多个客户端呢?每次手动写curl命令太麻烦了。而解决的方法就是利用Bus服务消息总线!!!
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。
基本原理:ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置。Spring Cloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架,它整合了Java的事件处理机制和消息中间件的功能。
Spring Clud Bus目前支持RabbitMQ和Kafka。
Spring Cloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道。
主要有以下两种消息通知方式,第一张图是利用消息总线触发某一个客户端 /bus/refresh,再由这个客户端触发其他的客户端进行通知,达到动态刷新,更新配置信息。
第二张图是利用消息总线触发一个服务端 /bus/refresh,再由服务端直接推送给相关的所有的客户端,实现动态刷新,更新配置信息。
PS: 显然第二张图更符合逻辑思想。因为第一张图描述的情况打破了微服务的职责单一性,客户端这里本身是业务模块,就不应该承担动态刷新配置的职责,同时也破坏了微服务各节点的对等性,也有一定的局限性。
2.项目源码
github源码地址:https://github.com/2656307671/SpringCloud-Hoxton-Bus
gitee源码地址:https://gitee.com/szh-forever-young/SpringCloud-Hoxton-Bus
首先在上一篇文章(Config服务配置)的基础上,再新建一个3366客户端模块。(等于说现在有7001服务注册中心、3344服务端、3355和3366两个客户端)
在这里Bus服务消息总线,我使用的是RabbitMQ,所以在pom文件中要添加相关的依赖、yml中要添加RabbitMQ的相关配置信息。
在启动测试之前,首先要确保你的RabbitMQ成功跑起来!!!在浏览器中输入:虚拟机IP:15672,即可访问RabbitMQ的web管理界面窗口。(这里说一下:15672是RabbitMQ Web管理界面的端口;5672是RabbitMQ访问的端口)
下面启动测试(顺序:7001、3344、3355、3366),首先可以看到Eureka服务注册中心中已经有了3344、3355、3366这三个微服务信息。
然后我们到gitee的springcloud-config仓库中将config-dev.yml文件做个小修改,将version改为4。
仓库地址:https://gitee.com/szh-forever-young/springcloud-config
修改完之后,到浏览器中测试,url:本机IP + 端口号 / git仓库分支 / 仓库中的某个文件。这里不需要写仓库名是因为3344的yml中已经配置了仓库地址。
可以看到3344正确无误的拿到了最新的配置数据,version=4。
下面,我们仍然使用curl来发送请求。
这里注意:上一篇文章Config服务配置中,实现动态刷新的命令是:curl -X POST "http://localhost:3355/actuator/refresh",这仅仅是针对3355一个客户端的。
现在我们做了改进,直接 curl -X POST "http://localhost:3344/actuator/bus-refresh" 向3344服务端发送请求,那么它将更新所有与自己相连的客户端的配置信息。也就是:一次发送,处处生效。
从上图可以看到,我们只向3344服务端发送了一次请求,它下面的3355、3366客户端全部实现了对配置信息的动态刷新。
此时我们可以在RabbitMQ的web管理界面窗口中看到多了一个交换机springCloudBus,而这个交换机其实就是:ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置。
最后再说一下,上面的案例是实现了利用消息总线触发了3344服务端下所有的客户端(3355、3366),实现了动态刷新。
当然也可以实现定点通知,就是说,我们只通知3355,不通知3366。公式:http://localhost:配置中心服务端的端口号/actuator/bus-refresh/{destination}。
例如:http://localhost:3344/actuator/bus-refresh/config-client:3355。
只所以是 config-client:3355,是因为我在3355微服务模块中将它的微服务名称定义为了config-client。
以上是关于SpringCloud Hoxton——Bus服务消息总线的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud Hoxton——OpenFeign服务接口调用
SpringCloud Hoxton——OpenFeign服务接口调用
SpringCloud Hoxton——Zookeeper服务注册与发现