【SpringCloud学习笔记】服务总线BUS

/ 微服务 / 没有评论 / 3000浏览

服务总线BUS

什么是消息总线

消息代理中间件构建一个共用的消息主题让所有微服务实例订阅,当该消息主题产生消息时会被所有微服务实例监听和消费。

消息代理又是什么?消息代理是一个消息验证、传输、路由的架构模式,主要用来实现接收和分发消息,并根据设定好的消息处理流来转发给正确的应用。它在微服务之间起到通信调度作用,减少了服务之间的依赖。

什么是SpringCloud Bus

Spring Cloud Bus 是 Spring Cloud 体系内的消息总线,用来连接分布式系统的所有节点。

Spring Cloud Bus 将分布式的节点用轻量的消息代理(RibbitMQ、Kafka)连接起来。可以通过消息代理广播配置文件的更改,或服务之间的通讯,也可以用于监控。解决了微服务数据变更,及时同步的问题。

官方文档:https://docs.spring.io/spring-cloud-bus/docs/3.0.2-SNAPSHOT/reference/html/#configuration-properties

img

SpringCloud Bus使用场景

什么时候使用 Spring Cloud Bus

微服务一般都采用集群方式部署,而且在高并发下经常需要对服务进行扩容、缩容、上线、下线的操作。比如我们需要更新配置,又或者需要同时失效所有服务器上的某个缓存,需要向所有相关的服务器发送命令,此时就可以选择使用 Spring Cloud Bus 了。

总的来说,就是在我们需要把一个操作散发到所有后端相关服务器的时候,就可以选择使用 Spring Cloud Bus 了。

安装RabbitMQ

具体看另外一篇博客。

全局更新案例

BUS动态刷新全局广播配置两种方案:

修改BUS服务端3344

修改pom.xml

添加maven依赖:spring-cloud-starter-bus-amqp

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

修改bootstrap.yml

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
management:
  endpoints:
    web:
      exposure:
        include: "bus-refresh"

修改BUS客户端3355

修改POM.XML

添加maven依赖:spring-cloud-starter-bus-amqp

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

修改bootstrap.yml

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

创建BUS客户端3366

创建maven项目

创建名为:cloud-config-client-3366

修改pom.xml

<parent>
        <artifactId>springcloud</artifactId>
        <groupId>info.huzd.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-config-client-3366</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

创建boostrap.yml

server:
  port: 3366

spring:
  application:
    name: config-client
  cloud:
    config:
      label: master
      name: config
      profile: dev
      uri: http://localhost:3344
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    virtual-host: /
eureka:
  instance:
    instance-id: cloudConfigClient3366
    prefer-ip-address: true
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
management:
  endpoints:
    web:
      exposure:
        include: "*"

创建启动类

@SpringBootApplication
@EnableEurekaClient
public class CloudConfigClient3366Application {

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

创建业务类

@RestController
@RefreshScope
public class ConfigController {

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

    @GetMapping("/configInfo")
    public String getConfigInfo(){
        return configInfo;
    }
}

启动

启动客户端3366

测试全局配置刷新

  1. 启动eureka7001
  2. 启动eureka7002
  3. 启动config server 3344
  4. 启动config client 3355
  5. 启动config client 3366
  6. 访问http://localhost:3344/master/config-dev.yml
  7. 访问http://localhost:3355/configInfo
  8. 访问http://localhost:3366/configInfo
  9. 修改gitlab配置文件
  10. 访问http://localhost:3344/master/config-dev.yml 发现配置文件更改已经获取
  11. 访问http://localhost:3355/configInfo & 访问http://localhost:3366/configInfo 发现配置文件未发生变化;
  12. 执行curl -X POST http://localhost:3344/actuator/bus-refresh
  13. 刷新访问http://localhost:3355/configInfo 发现配置文件最新信息已经获取
  14. 刷新访问访问http://localhost:3366/configInfo发现配置文件最新信息已经获取

总结

针对配置文件的修改;我们不需要逐个的访问客户端去更新配置;而是访问服务的接口;使用rabbitMQ来通知客户端各自进行更新。

指定更新案例

方法:

如果我们只想更新某个或者某些客户端那么需要做如下操作:

访问路径:http://localhost:3344/actuator/bus-refresh/{destination} 来刷新指定的客户端

{destination}为spring.application.name + “:” + server.port

例如:http://localhost:3344/actuator/bus-refresh/config-client:3355

测试:

  1. 修改gitlab
  2. 访问http://localhost:3344/master/config-dev.yml发现已经更新配置
  3. 访问http://localhost:3344/actuator/bus-refresh/config-client:3355
  4. 刷新http://localhost:3355/configInfo 发现配置已经更新
  5. 刷新http://localhost:3366/configInfo 发现配置并未更改