在上一篇文章的末尾,我们通过手动刷新才能读取变化后的配置,每个微服务需要加载最新配置信息,就需要手动发送post请求,才能加载最新配置信息,一般来说,微服务都是集群方式,所以这种方式不方便。
这篇文章中,我们使用组件Bus消息总线,实现自动刷新。Bus消息总线支持RabbitMQ和kafka。
详细解释:在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。
参考下面这篇文章,先搭建 RabbitMQ : https://www.longkui.site/program/development/win10-rabbitmq/5976/
什么是总线?
Spring Cloud Bus是用来将分布式系统的节点 与 轻量级消息系统 链接起来的框架
。
注意:它不属于消息中间件,他是通过和消息中间件整合,来完成服务之间消息通讯,类似于消息代理。
Spring Cloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道。
为什么被称为总线?
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题
,并让系统中所有微服务实例都连接上来
。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线
。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。
一般来说有下面两种设计思想:

第一种是触发其中一个客户端,通过客户端传递到消息总线,然后再经过消息总线通知其他客户端。这种一般不采用,因为增加了某个客户端的额外开销。

第二种是通知服务端,然后经过服务端,通知消息总线Bus,再油Bus通知各个客户端。实际开发中一般用第二种。
1.修改config服务端
我们从上一篇文章: spring cloud(七) config配置中心 的module中,打开config的服务端,添加消息总线支持
<!--集成RabbitMQ--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> <version>3.1.2</version> </dependency> <!--程序监控器--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>

然后在配置文件中加入RabbitMQ的配置信息。注意空格。
#rabbitmq相关配置
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
#暴露bus刷新配置的端点
management:
endpoints:
web:
exposure:
include: "bus-refresh"
注意,上面include:”bus-refresh”这种写法,如果按照以前的文章还是去请求bus-refresh这个地址,会报错405,具体解决办法看下面这篇文章:
这个地方经过测试,只要访问地址正确,写include:”bus-refresh” 和include:”busrefresh” 效果一样。
2.修改config-client并增加新的client
前面一篇文章我们已经增加了config-client,端口是30000。我们修改这个config-client的配置,增加RabbitMQ的相关配置
POM文件增加RabbitMQ的相关依赖:
<!--集成RabbitMQ-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
<version>3.1.2</version>
</dependency>
配置文件bootstrap.yml,增加rabbit的配置:

我们增加一个config-client,端口为40000,其他配置跟第一个client一样。启动后我们首先看一下是否在注册中心上线。

然后看一下RabbitMQ:


我们新增完以后整个测试框架如下:

3.测试全局广播
我们修改远程仓库中的信息,然后请求config-server的地址,看是否可以通知到其他客户端
curl -X POST "http://localhost:20000/actuator/busrefresh"

可以看到,其他客户端都收到了最新的配置信息。
4.单独通知某一个客户端
有的时候我们只需要通知某一个客户端更改配置,其他客户端保持不变,那么我们可以控制只通知其中一个客户端。
http://localhost:{配置端口号}/actuator/busrefresh/{需要变更配置的服务或者实例}
curl X -POST "http://localhost:20000/actuator/busrefresh/service-config-client:30000"

可以看到,我们通知了一个客户端,那么这个客户端会更新,另外一个客户端没有更新。
5.配合WebHooks使用
WebHooks相当于是一个钩子函数,我们可以配置当向Git仓库push代码时触发这个钩子函数,这里当我们向配置仓库push代码时就会自动刷新服务配置了。
这个功能需要公网IP,本文用localhost做的演示

