Spring Cloud Bus消息总线
概述
Spring Cloud Bus具有分布式自动刷新配置的功能,配合 Spring Cloud Config,即可实现配置的动态刷新
作用
SpringCloudBus能管理和传播分布式系统的消息,就像一个分布式执行器,可用于广播状态更改,事件推送等,也可以当做微服务的通信通道。
什么是总线
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以被称为消息总线。在总线上的各个实例,都可以方便的广播一些需要让其它连接在该主题上的实例都知道的消息。
基本原理
ConfigClient实例都监听MQ中同一个topic(默认是SpringCloudBus),当一个服务刷新数据的时候,它会被这个消息放到Topic中,这样其它监听同一个Topic的服务就能够得到通知,然后去更新自身的配置
上图是通过topic进行广播通知
RabbitMQ环境配置
1.Erlang安装
http://erlang.org/download/otp_win64_21.3.exe
安装完成之后,需要配置一下环境变量
系统变量:新建,变量值选你自己的erlang目录
用户变量:添加Path
%ERLANG_HOME%\bin
2.RabbitMQ安装
https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.14/rabbitmq-server-3.7.14.exe
3.启动管理功能
控制台进入RabbitMQ的sbin目录
以我的为例
rabbitmq-plugins enable rabbitmq_management
4.启动
选择start启动即可
4.测试
http://localhost:15672/
默认的用户名/密码都是guest,成功!
Spring Cloud Bus动态刷新全局广播
再创建一个Config客户端
1.创建cloud-config-client-3366模块
2.创建pom
<dependency><groupId>org.springframework.cloudgroupId><artifactId>spring-cloud-starter-configartifactId>dependency>
3.创建yml
bootstrap.yml
server:port: 3366spring:application:name: config-clientcloud:config:label: master name: config profile: dev uri: http://localhost:3344/ eureka:client:service-url:defaultZone: http://localhost:7001/eureka
management:endpoints:web:exposure:include: "*"
4.创建启动类
5.创建controller
package com.indi.springcloud.controller;&#64;RestController
&#64;RefreshScope
public class ConfigClientController{&#64;Value("${server.port}")private String serverPort;&#64;Value("${config.info}")private String configInfo;&#64;GetMapping("/configInfo")public String getConfigInfo(){return "serverPort&#xff1a;" &#43; serverPort &#43; "\t\n\n configInfo&#xff1a;" &#43; configInfo;}
}
设计思想
Spring Cloud Bus采用的是第二种设计思想
第一种
利用消息总线触发一个客户端/bus/refresh&#xff0c;而刷新所有客户端的配置
第二种
利用消息总线触发一个服务端ConfigServer的/bus/refresh端点&#xff0c;而刷新所有客户端的配置&#xff08;更加推荐&#xff09;
为什么不采用第一种呢&#xff1f;
理由如下
- 打破了微服务的职责单一性&#xff0c;因为微服务本身是业务模块&#xff0c;它不应该再承担配置刷新职责
- 破坏了微服务各节点的对等性
- 有一定的局限性&#xff0c;例如&#xff0c;微服务在迁移时&#xff0c;它的网络地址常常发生变化&#xff0c;此时如果想要做到自动刷新&#xff0c;那就会增加更多的修改。
给3344/3355/3366添加消息总线支持
3344/3355/3366的yaml
3344添加全部的&#xff0c;3355/3366只添加rabbitmq相关配置
rabbitmq:host: localhostport: 5672username: guestpassword: guest
management:endpoints:web:exposure:include: &#39;bus-refresh&#39;
3344/3355/3366的pom
<dependency><groupId>org.springframework.cloudgroupId><artifactId>spring-cloud-starter-bus-amqpartifactId>dependency>
测试
先启动7001、3344、3355、3366
修改之前&#xff0c;3344/3355/3366&#xff0c;version全部都是3
在线修改完Github文件之后&#xff0c;发送POST请求刷新总控中心
curl -X POST "http://localhost:3344/actuator/bus-refresh"
结果3344/3355/3366全部得到了刷新&#xff0c;成功实现了一次广播&#xff0c;处处通知。
Spring Cloud Bus动态刷新定点通知
定点通知&#xff0c;指定具体某一个实例生效而不是全部
测试
先启动7001、3344、3355、3366&#xff0c;在线修改完Github文件之后&#xff0c;查询3355/3366字段version的值都是4
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"
刷新完之后&#xff0c;只有3355发生了变化&#xff0c;3366还是没变&#xff0c;成功&#xff01;
总结