SpringCloud Bus消息总线
1、针对问题:
- 每次微服务都要执行一次post请求,手动刷新
- 可否广播?一次通知,处处生效
- 我们想大范围的自动刷新
2、概述
1、分布式自动刷新配置功能
2、SpringCloud Bus配合Springcloud Config使用可以实现配置的动态刷新
- 是什么
springCloud Bus是用来将分布式系统的节点与轻量级消息系统连接起来的框架,它整合了java的事件处理机制和消息中间件的功能
Bus支持两种消息代理:RabbitMQ和kafka
- 能干嘛
-
什么叫总线
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个公用的消息主题,并让系统中的所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他链接在该主题行的实例都知道的消息。 -
基本原来理:
ConfigClient实例都监听MQ中的同一个topic(默认是SpringcloudBus)。当一个服务刷新数据的时候,它会把这个信息放入到topic中,这样其它监听同一个topic的服务就能得到通知,然后去更新自身的配置。
3、RabbitMQ环境配置
在sbin目录下输入:
- rabbitmq-plugins enable rabbitmq_management
访问地址:
- http://localhost:15672/
默认账号密码
- guest
- guest
4、SpringCloud Bus动态刷新全局广播
-
必须先具备良好的RabbitMQ环境
-
演示广播效果增加复杂度,再以3355为模板制作一个3366
1、cloud-config-client-3366
2、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>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>
3、YML
server: port: 3366 spring: application: name: config-client cloud: config: label: master #分支名称 name: config #配置文件名称 profile: dev #读取后缀名称 上述三个综合http://localhost:3344/master/config-dev.yml uri: http://localhost:3344 #配置中心的地址 eureka: client: register-with-eureka: true service-url: defaultZone: http://localhost:7001/eureka management: endpoints: web: exposure: include: "*"
4、主启动类
@SpringBootApplication @EnableEurekaClient public class ConfigClientMain3366 { public static void main(String[] args) { SpringApplication.run(ConfigClientMain3366.class, args); } }
5、controller
@RefreshScope @RestController public class ConfigClientController { @Value("${config.info}") private String configInfo; //要访问的3344上的信息 @GetMapping("/configInfo") //请求地址 public String getConfigInfo(){ return configInfo; } }
-
设计思想
1、利用消息总线触发一个客户端/bus/refresh,而刷新所有客户端的配置
2、利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,而刷新所有客户端的配置
利用方法二的原因:
- 打破了微服务的职责单一性,因为微服务本身是业务模块,它不应该承担配置刷新的职责
- 打破了微服务各个节点的对等性
- 有一定的局限性。例如:微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就回增加更多的的修改
-
给3344配置中心服务端添加消息总线支持
1、修改pom文件
#增加 <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
2、修改YML
server: port: 3344 eureka: client: service-url: defaultZone: http://eureka7001.com:7001/eureka spring: application: name: cloud-config-center cloud: config: server: git: uri: https://github.com/ClqStart/SpringCloud-config.git force-pull: true search-paths: - SpringCloud-config label: master ##新增消息队列并且暴露 rabbitmq: host: localhost port: 5672 username: guest password: guest management: endpoints: web: exposure: include: 'bus-refresh'
-
给3355、3366配置中心服务端添加消息总线支持
1、POM
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
2、yml
rabbitmq: host: localhost port: 5672 username: guest password: guest
-
测试
1、修改GitHub上的配置文件增加版本
2、发送post请求
3、curl -X POST “http://localhost:3344/actuator/bus-refresh”
4、一次发送处处生效
结果
http://config-3344.com:3344/master/config-dev.yml
http://localhost:3355/configInfo
http://localhost:3366/configInfo
命令行发送curl -X POST "http://localhost:3344/actuator/bus-refresh"后
5、Springcloud Bus动态刷新定点通知
-
指定具体某一实例生效而不是全部
-
公式:http://lcoalhost:配置中心的端口号/actuator/bus-refresh/{destination}
-
/bus-refresh请求不再发送到具体的服务实例上,而是发给config server 。并通过destination参数类指定需要发送更新配置的服务或者实例
案例
我们只想刷新运行在3355端口上的config-client为例
curl -X POST “http://localhost:3344/actuator/bus-refresh/config-client:3355”
结果
- 通知总结