0.什么是Bus?
SpringCloud Bus是讲分布式系统的服务节点和轻量级消息系统连接起来的框架,它整合了java的事件处理机制和消息中间件的功能,目前支持RabbitMQ和kafka两种消息中间件。
什么是总线?
在微服务系统中,通常会用轻量级的消息系统去构建一个共同的消息主题,并让微服务中的所有服务实例链接上来。由于该主题中的产生的消息会被所有的实例监听和消费,所以叫做消息总线,在总线上的各个实例,可以广播一些想让别的实例收到的消息通知。
在上一章节中,我们实现了手动刷新config配置,在这里我们可以用bus来进行自动刷新,bus自动广播给所有订阅该主题的服务实例,来让这些实例来刷新配置。
1.安装RabbitMQ消息中间件
RabbitMq基于erlang开发,所以安装Rabbitmq之前需要先安装对应版本的erlang。
rabbitmq下载地址:https://www.rabbitmq.com/install-windows.html
erlang下载地址:https://www.erlang-solutions.com/resources/download.html
安装完,打开localhost:15672,使用guest,guest可登录rabbitmq,可以进行rabbitmq的操作。
2.使用Bus广播刷新多个客户端的config配置
首先,我们复制一份3355端口的客户端项目,并把端口改为3366。然后我们就有三个项目:
- 3344端口为服务端
- 3355端口为客户端1
- 3366端口为客户端2
我们要实现广播更新config,有两种思路
- 利用消息总线触发一个客户端暴露的bus-refresh从而刷新所有客户端配置
- 利用消息总线触发服务端configServer暴露的bus-refresh端点,从而刷新所有客户端
但是根据微服务的思想,每个服务应该有他各自的作用,而不是承担刷新其他客户端的职责,所以第二种思路更加合适。
接下来我们要使用bus消息总线,需要添加bus的pom依赖,对3344,3355,3366三个项目添加bus的依赖,这里我们选择使用Rabbitmq作为消息中间件,所以导入amqp的依赖。
<!--bus-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
然后在三个项目的配置文件中添加rabbitmq的配置,以及actuator监控暴露端点的配置。
rabbitmq的配置三个项目都一样,如下:
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
在3344服务端暴露bus-refresh端点的配置:
management:
endpoints:
web:
exposure:
include: "bus-refresh"
接下来开启3344,3355,3366三个项目,此时的git仓库中的配置文件为version=3,将git仓库的配置改为version=4,然后接下来需要去触发服务端的刷新,然后广播到所有客户端,实现刷新配置,以POST请求访问localhost:3344/actuator/bus-refresh
,然后在3355与3366两个客户端上查看配置看看是否更新。
3355客户端:
3366客户端:
可以看到,version都变成了4,自动刷新广播生效。
然后我们去rabbitmq的web管理页面localhost:15672去查看队列和交换机,发现bus给我们自动创建了一个交换机和3个服务实例所对应的队列。
交换机:
三个队列:
3.Bus动态刷新定点通知
在上面我们全部进行了消息通知,现在我们使用定点通知,只通知其中一个客户端刷新,例如只让3355端口的客户端进行刷新。
在上面我们请求localhost:3344/actuator/bus-refresh
进行动态全局刷新,现在我们使用localhost:3344/actuator/bus-refresh/{destination}
,用destination参数指定需要通知的实例或服务。
目前,git仓库中version=4,两个客户端也都是4,现在将git仓库中的改成5,然后POST请求localhost:3344/actuator/bus-refresh/cloud-config-client:3355
,后面跟的参数时application.name属性加上端口号。
3355端口的客户端的配置成功刷新了。
3366端口的没被刷新,实现了定点通知。