SpringCloud之bus消息总线

一、前言

1、使用背景

在学习完Config之后,我们发现了一个问题就是每当配置中心配置发生变化以后,都需要将每个微服务重新启动一遍,这样对于某些大型项目而言是很痛苦的,然后我们就又引入了动态刷新功能,每当配置中心配置变化后,我们的运维小哥就手动给每一个微服务都发送一个POST请求用于更新配置,这样便免于重新启动服务,节约时间,但是这样的动态刷新还是不够彻底,我们如何才能彻底解放运维小哥的双手呢?那就是使用Spring Cloud Bus配合Spring Cloud Config使用实现动态刷新配置

2、什么是总线

在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。在总线上的各个实例,都可以方便地广播─些需要让其他连接在该主题上的实例都知道的消息。

3、Spring Cloud Bus简介

Spring Cloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架,它整合了Java的事件处理机制和消息中间件的功能,它能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改、事件推送等,也可以当作微服务间的通信通道,目前支持RabbitMQ和Kafka,本文便是使用RabbitMQ。

二、工作流程

1、消息发送给一个客户端而刷新所有的配置

在这里插入图片描述

  1. 配置更新,推送到Git仓库。
  2. Config Server配置中心同步配置。
  3. 使用订阅了消息的主机给其中一个服务发送一个Post bus/refresh更新请求。
  4. 该服务向服务配置中心拉取最新配置,并将信息发送给消息总线。
  5. 这个消息将会通过消息总线广播出去,域内指定或所有服务收到消息就回去服务配置中心拉取最新配置。

2、消息发送给服务配置中心来刷新所有配置

在这里插入图片描述

  1. 配置更新,推送到Git仓库
  2. Config Server配置中心同步配置
  3. 使用订阅了消息的主机给服务配置中心发送一个Post bus/refresh更新请求
  4. 服务配置中心给消息总线发送通知请求刷新配置
  5. 消息总线向域内指定或所有服务发送更新通知消息
  6. 服务从服务配置中心拉取最新配置

3、采用第二种的原因

相比之下,第二种应该更合理,图一不合理的原因如下:

  • 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责。如果这个服务挂了,那是不是就会既影响订单服务,又影响通知服务,数罪并罚死得更惨。
  • 破坏了微服务各节点的对等性
  • 有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改

三、基本原理

ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic的服务就能得到通知,然后去更新自身的配置。

四、RabbitMQ安装及环境配置

这里只提供官网下载地址,具体配置自行百度

1、ErLang

使用RabbitMQ时需要下载安装ErLang环境,因为RabbitMQ是用ErLang语言编写的。
官网下载地址:ErLang下载

2、RabbitMQ

官网下载地址:RabbitMQ下载

五、实现动态刷新

1、创建一个新的客户端

基于上一篇文章,再次创建一个与8888相同的8889,步骤省略,区别仅在于配置文件端口号声明为8889

2、ConfigServer8080添加消息总线的支持

这里采用第二种通知方式,直接通知配置中心,更加合理

(1)pom文件
<!-- 添加消息总线RabbitMQ支持 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
(2)yml文件
server:
  port: 8080

spring:
  application:
    name:  cloud-config-center #注册进Eureka服务器的微服务名
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/F_promise/springcloud-config.git #GitHub上面的git仓库名字
        ####搜索目录
          search-paths:
            - springcloud-config
      ####读取分支
      label: master
#rabbitmq相关配置
rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

#服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

##rabbitmq相关配置,暴露bus刷新配置的端点
management:
  endpoints: #暴露bus刷新配置的端点
    web:
      exposure:
        include: 'bus-refresh'

3、ConfigClient添加消息总线的支持

8888,8889配置相同

(1)pom文件
<!-- 添加消息总线RabbitMQ支持 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
(2)yml配置文件
server:
  port: 8888

spring:
  application:
    name: config-client
  cloud:
    #Config客户端配置
    config:
      label: master #分支名称
      name: config #配置文件名称
      profile: dev #读取后缀名称   上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
      uri: http://localhost:8080 #配置中心地址k

#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

#服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

# 暴露监控端点
management:
  endpoints:
    web:
      exposure:
        include: "*"

4、重启测试

  1. 先单独访问每个项目,查看是否能正常访问
  2. 修改git仓库的内容
  3. 查看服务端ConfigServer8080是否能正常自动更新数据
  4. 8080上的数据可以正常更新后,发送post请求:curl -X POST “http://localhost:3344/actuator/bus-refresh”
  5. 再次访问客户端8888和8889,可以发现内容也进行了实时更新。

六、动态刷新的定点通知

在配置更新后,我们有时候有这种需求,只希望某一部分服务更新配置,另一部分不更新,那么就需要进行定点通知,放在本文中,也就是只通知8888或者8889,另一个不通知。

这里给个公式:

http://localhost:配置中心的端口号/actuator/bus-refresh/{destination}

请求就会发给config server并通过destination参数类指定需要更新配置的服务或实例
例如:

#只通知8888,config-client为服务名
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:8888" 
#只通知8889
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:8889"
#假如我们现在有三个客户端888888898890,但是想通知88888889,不通知8890
curl -X POST "http://localhost:3344/actuator/bus-refresh/{config-client:8888,config-client:8889}"
#或者
curl -X POST "http://localhost/bus/refresh?destination=config-client:8888&config-client:8889"
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值