欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Springcloud笔记——Bus消息总线

程序员文章站 2022-07-13 08:33:24
...

概述


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

1、Bus是什么?

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

Springcloud笔记——Bus消息总线

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

2、Bus能干吗?

Springcloud笔记——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,从而刷新所有客户端配置

Springcloud笔记——Bus消息总线

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

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

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

Springcloud笔记——Bus消息总线

上图利用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

Springcloud笔记——Bus消息总线

改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

Springcloud笔记——Bus消息总线

运维工程师

运维工程师修改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、总结

Springcloud笔记——Bus消息总线