SpringCloud(十):Bus消息总线【Greenwich 版】

我们在前面讲到,如果需要客户端获取到最新的配置信息需要执行 refresh,我们可以利用 Webhook 的机制每次提交代码发送请求来刷新客户端,当客户端越来越多的时候,需要每个客户端都执行一遍,这种方案就不太适合了。使用 Spring Cloud Bus 可以完美解决这一问题。

Spring Cloud Bus 通过轻量消息代理连接各个分布的节点。这会用在广播状态的变化(例如配置变化)或者其他的消息指令。Spring Bus 的一个核心思想是通过分布式的启动器对 Spring Boot 应用进行扩展,也可以用来建立一个多个应用之间的通信频道。目前唯一实现的方式是用 Amqp 消息代理作为通道,同样特性的设置(有些取决于通道的设置)在更多通道的文档中。

Spring Cloud Bus 被国内很多都翻译为消息总线。大家可以将它理解为管理和传播所有分布式项目中的消息既可,其实本质是利用了 MQ 的广播机制在分布式的系统中传播消息,目前常用的有 Kafka 和 RabbitMQ。利用 Bus 的机制可以做很多的事情,其中配置中心客户端刷新就是典型的应用场景之一,我们用一张图来描述 Bus 在配置中心使用的机制。
在这里插入图片描述

改造配置中心

本文消息队列使用RabbitMQ,改造config-server-8009,config-server-8010模块,添加依赖 spring-cloud-starter-bus-amqp

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<!--使用消息总线时加入-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

两个配置文件添加的一样

server:
  port: 8009
spring:
  application:
    name: config-server
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
  cloud:
    config:
      server:
        git:
          uri: https://github.com/ROAOR1/config-server.git
          username:
          password:
          search-paths: config #要搜索的路径,填我们刚刚创建的文件夹
    bus:
      enabled: true
      trace:
        enabled: true
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/
management:
  endpoints:
    web:
      exposure:
        include: bus-refresh #暴露出bus-refresh接口

启动类还是和之前一样

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

至此,服务端改造完成

改造客户端

改造config-client-8011,config-client-8012模块,添加依赖 spring-cloud-starter-bus-amqp

<!--是用来接收更新的消息,类似心跳检测-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<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>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

配置分为两个文件,首先是application.yml

server:
  port: 8012
spring:
  application:
    name: config-client2
  cloud:
    bus:
      enabled: true
      trace:
        enabled: true
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
data: ${spring.profiles.active} #用这个来加载配置中心中的数据

bootstrap.yml

spring:
  cloud:
    config:
      name: cloud-config #对应 {application}
      label: master #对应{label}
      profile: dev #对应{profile}
      discovery:
        enabled: true #开启 Config 服务发现支持
        service-id: config-server #配置中心Id
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8001/eureka/,http://localhost:8002/eureka/
management:
  endpoints:
    web:
      exposure:
        include: refresh #暴露了refresh接口

启动类和之前一样

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

测试类也和之前一样,不要忘了@RefreshScope注解

@RefreshScope
@RestController
public class ConfigController {
    @Value("${data}")
    private String data;

    @RequestMapping("/getData")
    public void getData(){
        System.out.println(data);
    }
}

至此,客户端改造完成

测试

接着我们启动本地RabbitMQ,启动程序,分别访问测试接口http://localhost:8011/getData,http://localhost:8012/getData,看到如下结果
在这里插入图片描述
在这里插入图片描述
修改github上的配置文件,将dev改成dev bus,接着我们访问服务端的刷新接口http://localhost:8009/actuator/bus-refresh,再次访问测试接口http://localhost:8011/getData,http://localhost:8012/getData,会发现数据改变
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

思考

这里我们再想一个问题:如果对客户端使用 /actuator/bus-refresh 会发生什么呢?是只刷新了当前客户端还是刷新全部客户端,还是一个都没刷新呢?不如来试一下吧:
首先我们需要把客户端上的 bus-refresh 端点给放出来

management:
  endpoints:
    web:
      exposure:
        include: refresh,bus-refresh #暴露了refresh接口,bus-refresh接口是在添加消息总线时暴露

重启客户端,再进行上面的测试,这次访问客户端的刷新接口http://localhost:8012/actuator/bus-refresh
会发现两个客户端结果都改变了。

说明只要开启 Spring Cloud Bus 后,不管是对 config-server 还是 config-client 执行 /actuator/bus-refresh 都是可以更新配置的。

最后我们就可以使用git的Webhook(上章有讲到),达到当修改配置文件时,通过消息总线自动刷新配置的目的。

参考

Spring Cloud(九):配置中心(消息总线)【Finchley 版】

相关阅读

项目代码
SpringCloud 汇总【Greenwich 版】
SpringCloud(一):Eureka注册中心【Greenwich 版】
SpringCloud(二):Ribbon负载均衡【Greenwich 版】
SpringCloud(三):Feign声明式服务调用【Greenwich 版】
SpringCloud(四):Hystrix熔断器介绍【Greenwich 版】
SpringCloud(五):Hystrix的请求熔断与服务降级【Greenwich 版】
SpringCloud(六):Hystrix的请求合并【Greenwich 版】
SpringCloud(七):Hystrix仪表盘与Turbine集群监控【Greenwich 版】
SpringCloud(八):Zuul网关【Greenwich 版】
SpringCloud(九):Config配置中心【Greenwich 版】
SpringCloud(十):Bus消息总线【Greenwich 版】
SpringCloud(十一):Stream消息驱动 + RabbitMQ【Greenwich 版】
SpringCloud(十二):Sleuth链路跟踪【Greenwich 版】

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值