什么是微服务?一看就会系列!
一、手把手教你搭建SpringCloud项目(一)图文详解,傻瓜式操作
二、手把手教你搭建SpringCloud项目(二)生产者与消费者
三、手把手教你搭建SpringCloud项目(三)集成Eureka服务注册中心
四、手把手教你搭建SpringCloud项目(四)Eureka集群版搭建
五、手把手教你搭建SpringCloud项目(五)生产者集群版搭建
六、手把手教你搭建SpringCloud项目(六)Eureka实现服务发现
七、手把手教你搭建SpringCloud项目(七)集成Consul服务注册中心
八、手把手教你搭建SpringCloud项目(八)集成Ribbon负载均衡器
九、手把手教你搭建SpringCloud项目(九)集成OpenFeign服务接口调用
十、手把手教你搭建SpringCloud项目(十)集成Hystrix之服务降级
十一、手把手教你搭建SpringCloud项目(十一)集成Hystrix之服务熔断
十二、手把手教你搭建SpringCloud项目(十二 )集成Hystrix之图形化Dashboard实时监控
十三、手把手教你搭建SpringCloud项目(十三 )集成Gateway新一代网关
十四、手把手教你搭建SpringCloud项目(十四 )集成Config分布式配置中心
十五、手把手教你搭建SpringCloud项目(十五)集成Bus消息总线
十六、手把手教你搭建SpringCloud项目(十六)集成Stream消息驱动
十七、手把手教你搭建SpringCloud项目(十七)集成Sleuth分布式链路跟踪
继续更新中,欢迎点赞关注!
用SpringCloud Config时,我们可以实现配置信息手动的动态刷新,也就是远端配置信息发生改变后,需要告诉服务端配置信息发生变化后,服务端才会更新配置信息,而现在我们想要实现分布式自动刷新配置信息功能,这就需要我们使用SpringCloud Bus消息总线配合SpringCloud Config实现配置信息的动态刷新。SpringCloud Bus是用来将分布式系统的节点与轻量级消息系统连接起来的框架,整合了Java的事件处理机制和消息中间件的功能,SpringCloud Bus目前支持两种消息代理:RabbitMQ和Kafka。SpringCloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等, 也可以当做微服务间的通信通道。
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来,由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。
SpringCloud Config客户端的实例都监听消息队列中的同一个主题(topic)(默认是SpringCloud Bus),当一个服务器刷新数据的时候,它会把这个信息放入到主题中,这样其他监听了同一主题的服务就能得到通知,然后去更新自身的配置。
在学习SpringCloud Config的时候我们已经建立了服务cloud-config-client-3355作为Config的客户端,这里为了演示广播效果,我们增加复杂度,再以3355为模板再制作另一个Config的客户端3366,建立Module:cloud-config-client-3366,其结构和cloud-config-client-3355类似,修改下服务端口号即可
消息总线的两种设计思想:
方案一:利用消息总线触发一个客户端/bus/refresh端点,而后刷新所有客户端的配置:
方案二:利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,而后刷新所有客户端的配置:
明显第二种架构更加合适,第一种架构不合适的原因主要有:
打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责;
破坏了微服务各节点的对等性;
有一定的局限性,比如在微服务迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改。
所以虽然从技术上两种方案都可以实现,但是无疑在技术选型上我们应该选择第二种方案。
在其POM文件中添加使用RabbitMQ实现消息总线的依赖:
<!--添加消息总线RabbitMQ支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
然后在其yaml配置文件中添加RabbitMQ的相关配置,暴露SpringCloud Bus刷新配置的端点
# RabbitMQ相关配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
# 暴露总线刷新配置的端点
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
在其POM文件中添加RabbitMQ实现总线的依赖(同ConfigServer的相关依赖):
<!--添加消息总线RabbitMQ支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
然后在其yaml配置文件中添加RabbitMQ的相关配置:
# RabbitMQ相关配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
按顺序启动Eureka服务注册中心7001/7002,ConfigServer配置中心3344,ConfigClient配置中心客户端3355/3366,此时远端GitHub上的配置信息如下:
config:
info: "spring cloud config-dev, version=3"
然后将GitHub远端的配置信息中的版本号改为4,然后对服务配置中心发送POST请求:
curl -X POST "{配置中心的地址}/actuator/bus-refresh"
如,此时我们该发送的POST请求为:
curl -X POST "http://localhost:3344/actuator/bus-refresh"
发现所有服务的配置信息都得到了更新,打开RabbitMQ的控制面板,我们可以发现有一个交换机,这就对应消息总线发送消息的交换机:
再全局广播中,我们更新配置文件的信息对所有服务都进行了通知,但是假设我们只想通知3355,而不想通知3366又该怎么办呢,这就需要我们用定点通知的方法通知3355,也就是说我们进行消息通知时只指定具体某个实例生效而不是全部生效,这种情况下就需要修改我们发送的POST请求:
curl -X POST "http://{配置中心的地址}/actuator/bus-refresh/{destination}"
这样的话,/bus/refresh请求就不再发送到具体的服务实例上,而是发给ConfigServer配置中心并通过destination参数指定需要更新配置的服务或实例。其中destination具体为微服务+端口号。
比如现在我们修改远端配置文件,但是我们只想通知3355的配置更新信息,而不想通知3366,此时我们发送的POST请求就应该是:
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"
修改GitHub上远端配置文件信息,将版本号改为5,然后对服务配置中心发送上面的POST请求,
此时我们再访问配置中心及其客户端的配置中心,我们发现3355的配置信息得到了更新,而3344的配置中心仍然是之前的配置:
我们Spring Cloud Bus到这里就学习完毕了,so easy!
由于时间原因就转发的其他小伙伴六甲横宝的文章,点击查看原文!
下一篇文章我们学习Spring Cloud Stream消息驱动,持续学习,持续更新,下一节更精彩!欢迎朋友们点赞关注!感谢!