十一、消息总线 SpringCloud Bus

上一讲解的加深和扩充,一言以蔽之,分布式自动刷新配置功能;Spring Cloud Bus配合Spring Cloud Config使用可以实现配置的动态刷新

一、概述

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

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

  Spring Cloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改,事件推送等,也可以当做微服务键的通信息通道。

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

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

二、RabbitMQ环境配置

1、安装Erlang,:

  下载地址:http://erlang.org/download/otp_win64_21.3.exe

  安装:一直下一步

2、安装RabbitMQ

  下载地址:https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.14/rabbitmq-server-3.7.14.exe

  安装:一直下一步,进入RabbitMQ安装目录下的sbin目录,输入以下命令启动管理功能

rabbitmq-plugins enable rabbitmq_management

  访问地址查看是否安装成功:http://localhost:15672/;输入账号密码并登录: guest guest

三、SpringCloud Bus动态刷新全局广播

3.1、以3355为模板再制作一个3366

  • 新建Spring Boot 的Module名称 :cloud-config-client-3366
  • pom.xml添加如下依赖
<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>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</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-test</artifactId>
    <scope>test</scope>
  </dependency>
</dependencies>
  • 编写application.yml
server:
  port: 3366

spring:
  application:
    name: config-client
  cloud:
    config:
      label: master
      name: config
      profile: dev
      uri: http://localhost:3344
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
management:
  endpoints:
    web:
      exposure:
        include: "*"
  • 主启动 
@EnableEurekaClient
@SpringBootApplication
public class ConfigClientMain3366 {
    public static void main(String[] args) {
            SpringApplication.run( ConfigClientMain3366.class,args);
        }
}
  • controller
@RestController
@RefreshScope
public class ConfigClientController {

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

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


    @GetMapping("/configInfo")
    public String getConfigInfo(){
        return "serverPort:"+serverPort+"\t\n\n configInfo: "+configInfo;
    }
}

3.2、设计思想

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

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

  图二的架构显然更加合适,图一不适合的原因如下

    • 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新职责

    • 破坏了微服务各节点的对等性

    • 有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改

3.3、给cloud-config-center-3344配置中心服务端添加消息总线支持 

  • pom.xml添加如下依赖
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
  • 编写application.yml
server:
  port: 3344
spring:
  application:
    name: cloud-config-center
  cloud:
    config:
      server:
        git:
          uri:  https://github.com/hhf19906/springcloud-config.git  #git@github.com:hhf19906/springcloud-config.git
          search-paths:
            - springcloud-config
      label: master
 
 rabbitmq:# 注意和cloud平级
    host: localhost
    port: 5672
    username: guest
    password: guest

eureka:
  client:
    service-url:
      defaultZone:  http://localhost:7001/eureka

management:
  endpoints:
    web:
      exposure:
        include: 'bus-refresh'

3.4、给cloud-config-center-3355客户端添加消息总线支持

  • pom.xml添加如下依赖
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
  • 编写application.yml
server:
  port: 3355

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

eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka
management:
  endpoints:
    web:
      exposure:
        include: "*"

3.5、给cloud-config-center-3366客户端添加消息总线支持

  • pom.xml添加如下依赖
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
  • 编写application.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

eureka:
  client:
    service-url:
      defaultZone:  http://localhost:7001/eureka

management:
  endpoints:
    web:
      exposure:
        include: '*'

3.6、测试

四、SpringCloud Bus动态刷新定点通知

  不想全部通知,只想定点通知,只通知3355不通知3366,简单一句话,指定具体某一个实例生效而不是全部

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

  /bus/refresh请求不再发送到具体的服务实例上,而是发给config server并通过destination参数类指定需要更新配置的服务或实例。

  案例

  我们这里以刷新运行在3355端口上的config-client为例(只通知3355/不通知3366)

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

  通知总结All

posted @ 2021-04-22 11:14  jingdy  阅读(233)  评论(0编辑  收藏  举报