SpringCloud配置中心--svn(五)配置中心和消息总线【完结】

it2022-05-06  7

我们在SpringCloud配置中心–svn(三)refresh中讲到,如果需要客户端获取到最新的配置信息需要执行refresh,但是当客户端越来越多的时候,需要每个客户端都执行一遍,这种方案就不太适合了。使用Spring Cloud Bus可以完美解决这一问题。

Spring Cloud Bus

Spring cloud bus通过轻量消息代理连接各个分布的节点。这会用在广播状态的变化(例如配置变化)或者其他的消息指令。Spring bus的一个核心思想是通过分布式的启动器对spring boot应用进行扩展,也可以用来建立一个多个应用之间的通信频道。目前唯一实现的方式是用AMQP消息代理作为通道,同样特性的设置(有些取决于通道的设置)在更多通道的文档中。

Spring cloud bus被国内很多都翻译为消息总线,也挺形象的。大家可以将它理解为管理和传播所有分布式项目中的消息既可,其实本质是利用了MQ的广播机制在分布式的系统中传播消息,目前常用的有Kafka和RabbitMQ。利用bus的机制可以做很多的事情,其中配置中心客户端刷新就是典型的应用场景之一,我们用一张图来描述bus在配置中心使用的机制。

根据此图我们可以看出利用Spring Cloud Bus做配置更新的步骤:

1、提交代码触发post给客户端A发送bus/refresh 2、客户端A接收到请求从Server端更新配置并且发送给Spring Cloud Bus 3、Spring Cloud bus接到消息并通知给其它客户端 4、其它客户端接收到通知,请求Server端获取最新配置 5、全部客户端均获取到最新的配置 项目示例

我们选择前二篇文章SpringCloud配置中心–svn(四)服务化和高可用版本的示例代码来改造,MQ我们使用RabbitMQ来做示例。

RabbitMQ安装见:RabbitMQ安装教程

客户端spring-cloud-config-client改造 1、添加依赖

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>

需要多引入spring-cloud-starter-bus-amqp包,增加对消息总线的支持

2、配置文件 application.properties 添加以下配置

开启消息跟踪

spring.cloud.bus.trace.enabled=true spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest

配置文件需要增加RebbitMq的相关配置和开启消息跟踪配置,这样客户端代码就改造完成了。

3、测试

依次启动spring-cloud-eureka、spring-cloud-config-server、spring-cloud-config-client项目,在启动spring-cloud-config-client项目的时候我们会发现启动日志会输出这样的一条记录。

说明客户端已经具备了消息总线通知的能力了,为了更好的模拟消息总线的效果,我们更改客户端spring-cloud-config-client项目的端口为8003、8004依次启动,这样测试环境就准备好了。启动后eureka后台效果图如下:

我们先分别测试一下服务端和客户端是否正确运行, 访问:http://localhost:8001/client8002/client8002-config-dev.properties 返回信息:

说明server端正常读取到了配置信息。

在依次访问: http://localhost:8002/hello http://localhost:8003/hello http://localhost:8004/hello 返回

说明客户端都已经读取到了server端的内容

现在我们更新 client8002-config-dev.properties client8003-config-dev.properties client8004-config-dev.properties 中hello的值分别为 springCloud-8002 update springCloud-8003 update springCloud-8004 update 并提交SVN 访问:http://localhost:8002/hello 依然返回:springCloud-8002

我们对端口为8002的客户端发送一个/bus/refresh的post请求。 打开cmd 运行 curl -X POST http://localhost:8002/bus/refresh

执行完成后,依次访问: http://localhost:8002/hello http://localhost:8003/hello http://localhost:8004/hello 返回

说明三个客户端均已经拿到了最新的配置文件信息,这样我们就实现了一个客户端刷新,所有客户端同步更新配置的功能,也就是图一的示例。

改进版本

在上面的流程中,我们已经到达了利用消息总线触发一个客户端bus/refresh,而刷新所有客户端的配置的目的。但这种方式并不优雅。原因如下:

打破了微服务的职责单一性。微服务本身是业务模块,它本不应该承担配置刷新的职责。 破坏了微服务各节点的对等性。 有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就不得不修改WebHook的配置。 因此我们将上面的架构模式稍微改变一下

这时Spring Cloud Bus做配置更新步骤如下:

1、提交代码触发post请求给bus/refresh 2、server端接收到请求并发送给Spring Cloud Bus 3、Spring Cloud bus接到消息并通知给其它客户端 4、其它客户端接收到通知,请求Server端获取最新配置 5、全部客户端均获取到最新的配置 这样的话我们在server端的代码做一些改动,来支持bus/refresh

1、添加依赖

<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>

需要多引入spring-cloud-starter-bus-amqp包,增加对消息总线的支持

2、配置文件 application.yml

server: port: 8001 spring: cloud: config: server: svn: uri: file:///D:/svn-repository/trunk username: chenqi password: 123456 default-label: client8002,client8003,client8004 profiles: active: subversion application: name: spring-cloud-config-server rabbitmq: host: localhost port: 5672 username: guest password: guest eureka: client: serviceUrl: defaultZone: http://localhost:8080/eureka/ ## 注册中心eurka地址 management: security: enabled: false

配置文件增加RebbitMq的相关配置,关闭安全验证。这样server端代码就改造完成了。

3、测试 启动spring-cloud-config-server

按照上面的测试方式,访问server端和三个客户端测试均可以正确返回信息。 同样修改 client8002-config-dev.properties client8003-config-dev.properties client8004-config-dev.properties 中hello的值分别为 springCloud-8002 update 222 springCloud-8003 update 333 springCloud-8004 update 444 并提交SVN 在win下使用下面命令来模拟webhook触发server端bus/refresh.

执行完成后,依次访问: http://localhost:8002/hello http://localhost:8003/hello http://localhost:8004/hello 返回

说明三个客户端均已经拿到了最新配置文件的信息,这样我们就实现了上图中的示例。 至此,一个完整的springCloud配置中心案例基本完成。

ps:文中部分原理说明和图片来源于网络,如有侵权请联系本人删除。


最新回复(0)