Springcloud笔记——Bus消息总线

概述


根据Spring Cloud Config配置中心,当我们更改了GitHub上面的配置文件后,若想要获取到最新的配置,需要手动刷新或者利用webhook的机制每次提交代码发送请求来刷新客户端,客户端越来越多的时候,需要每个客户端都执行一遍,这种方案很不好。使用Spring Cloud Bus(消息总线)可以解决这一问题

1、Bus是什么?

Spring Cloud Bus 配合 Spring Cloud Config 使用可以实现配置的自动刷新

在这里插入图片描述

Spring Cloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架
它整合了Java的事件处理机制和消息中间件的功能
Spring Cloud Bus目前只支持RabbitMQ和Kafka

2、Bus能干吗?

在这里插入图片描述

Bus能管理和传播分布式系统间消息,像一个分布式执行器,可用于广播状态更改、时间推送等

Bus也可用做微服务间的通信通道

3、Bus为何被称为总线

3.1什么是总线?

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

3.2基本原理

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

RabbitMQ环境配置


详细请看另一篇文章:https://blog.csdn.net/qq_43240702/article/details/109629176

SpringCloud Bus动态刷新全局广播


1、环境

必须先具备良好的RabbitMQ环境,可以自己测试一下:http://ip:15672

2、设计思想

利用消息总线触发一个客户端/bus/refresh,从而刷新所有客户端配置

在这里插入图片描述

上图利用Spring Cloud Bus做配置更新的步骤

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

利用消息总线触发一个ConfigServer服务端的/bus/refresh端点,从而刷新所有客户端配置

在这里插入图片描述

上图利用Spring Cloud Bus做配置更新的步骤

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

第二种架构显然更加合适,第一种架构不合适的理由如下

  • 破坏了微服务各个节点的对等性
  • 打破了微服务的职责单一性,因为其本身是业务模块,本不应该承担配置刷新职责
  • 有一定的局限性,例如微服务迁移时,网络地址常常发生变化,此时若想做到自动刷新,需增加更多修改

3、制作新模块

根据之前的cloud-config-client3355在制作一个cloud-config-client3366客户端

建module

在这里插入图片描述

改POM

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>com</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

YML

bootstrap.yml

server:
  port: 3355

spring:
  application:
    name: config-client
  cloud:
    #config客户端配置
    config:
      label: main   #分支名称
      name: config  #配置文件名称
      profile: dev  #读取后缀名称
                    #上述三个综合:main分支上config-dev.yml的配置文件被读取     http://localhost:3344/main/config-dev.yml
      uri: http://localhost:3344  #配置文件中心地址
      
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka

主启动

@SpringBootApplication
public class ConfigClientMain3366 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClientMain3366.class,args);
    }
}

业务类

@RefreshScope
@RestController
public class ConfigClientController {

    @Value("${server.port}")
    private String serverPort;

    @Value("${config.info}")
    private String configInfo;

    @GetMapping("/configInfo")
    public String getConfigInfo(){
        return "server port : " + serverPort + " config info : " + configInfo;
    }
}

4、3344配置中心服务端添加消息总线支持

POM

<!-- 添加消息总线RabbitMQ支持 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

YML

新增两块配置

spring:
    rabbitmq:
      host: 自己的ip
      port: 5672
      username: guest
      password: guest

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

5、3355与3366客户端添加消息总线支持

POM

<!-- 添加消息总线RabbitMQ支持 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

YML

spring:
    rabbitmq:
      host: 自己的ip
      port: 5672
      username: guest
      password: guest
      
management:
  endpoints:
    web:
      exposure:
        include: "*"

6、测试

启动各个模块

先启动 eureka 注册中心7001,在启动服务配置中心3344,随后启动客户端3355与3366

在这里插入图片描述

运维工程师

运维工程师修改GitHub上的配置文件增加版本号

测试3344配置中心

http://localhost:3344/main/config-dev.yml

返回结果

config:
  info: master branch,springcloud-config/config-dev.yml version=6
测试3355与3366

http://localhost:3355/configInfo

返回结果

master branch,springcloud-config/config-dev.yml version=5

http://localhost:3366/configInfo

返回结果

server port : 3366 config info : master branch,springcloud-config/config-dev.yml version=5

可以看到客户端3355,3366并没有动态刷新

刷新

运维然后发送POST请求 —> curl -X POST “http://localhost:3344/actuator/bus-refresh”

再次测试3355、3366

http://localhost:3355/configInfo

返回结果

master branch,springcloud-config/config-dev.yml version=6

http://localhost:3366/configInfo

返回结果

server port : 3366 config info : master branch,springcloud-config/config-dev.yml version=6

可以看到已经成功!达到了一次修改,广播通知,处处生效

SpringCloud Bus动态刷新定点刷新


问题:不想全局通知,只想定点通知

假设我们只想通知3355,不想通知3366

1、说明

  • 指定具体某一个实例生效而不是全部
  • http://localhost:配置中心端口号/actuator/bus-refresh/{destination}
  • /bus/refresh请求不再发送到具体的服务实例上,而是发给config server并通过destination参数类指定需要更新配置的服务或者实例

2、案例

我们在这里以只刷新运行在3355端口上的config-client为例

curl -X POST “http://localhost:3344/actuator/bus-refresh/config-client:3355”

注:最后为微服务名称 + 端口号

测试3355显示已经刷新最新配置,而未被通知的3344不会进行刷新

3、总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大恐龙的小弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值