- 消息总线Spring Cloud Bus
- 一、SpringCloudBus介绍
- 二、SpringCloudBus使用
- 1. 运行rabbitmq
- 2. 创建SpringConfig客户端(3366)
SpringCLoudBus配合SpringCloudConfig使用可以实现配置的动态刷新。
SpringCLoudBus是用来将分布式系统的节点与轻量级消息系统连接起来的框架,它整合了Java的事件处理机制和消息中间件的功能。SpringCloudBus目前支持RabbitMq和Kafka。
Spring Cloud Bus能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更改,事件推送等,也可以当做微服务间的通信通道。
什么是总线?
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个公共的消息主题,并让系统中所有微服务实例都连接起来。由于该主题中产生的消息会被所有实例监听和消费,所以称他为消息总线。在总线上的各个实例,都可以方便的广播一些需要让其他连接在该主题上的实例都知道的消息。
基本原理:
ConfigClient实例都监听MQ中同一个topic(默认是SpringCloudBus)。当一个服务刷新数据的时候,他会把这个消息放入到Topic中,这样其他监听同一个Topic的服务就能得到通知,然后去更新自身的配置。
二、SpringCloudBus使用 1. 运行rabbitmq
这里我们选择使用Docker运行,由于我们需要访问他的web页面,所以我们选择rabbitmq:management。
- 下载rabbtimq:management镜像
- 新建容器并启动,由于这里我们开放了俩个端口:15672(管理界面的端口)和5672(服务的端口)
- 测试访问
- pom
cloud2021 com.atguigu.springcloud 1.0-SNAPSHOT 4.0.0 cloud-config-client-3366 org.springframework.cloud spring-cloud-starter-config org.springframework.cloud spring-cloud-starter-openfeign org.springframework.cloud spring-cloud-starter-netflix-eureka-client org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-actuator org.springframework.boot spring-boot-devtools runtime true org.projectlombok lombok org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-devtools runtime true com.atguigu.springcloud cloud-api-commons 1.0-SNAPSHOT compile
- bootstrap.yml文件
server:
port: 3366
spring:
application:
name: config-client # 注册进Eureka服务器的微服务名
cloud:
config:
label: master # 分支名称
name: config # 配置文件名称
profile: dev # 读取后缀名称 上述三个综合:master分支上config-dev.yml的配置文件被读取http://localhost:3344/master/config-dev.yml
uri: http://localhost:3344
# 服务注册到Eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
- 主启动类
package com.atguigu.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ConfigClientMain3366 {
public static void main(String[] args){
SpringApplication.run(ConfigClientMain3366.class,args);
}
}
- 控制层Controller
package com.atguigu.springcloud.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${config.info}")
private String configInfo;
@GetMapping("/configInfo")
private String getConfigInfo(){
return configInfo;
}
}
到了这里要先介绍一下Bus的设计思想:
-
利用消息总线触发一个客户端/bus/refresh,而刷新所有客户端的配置
-
利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,而刷新所有客户端的配置
显然图二的架构更加适合,图一不适合的原因如下:
- 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责。
- 破坏了微服务各节点的对等性。
- 有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改。
所以我们需要在我们的ConfigServer端增加依赖:
org.springframework.cloud
spring-cloud-starter-bus-amqp
然后增加ConfigSever端的yml配置信息:
spring:
application:
name: cloud-config-center # 注册进Eureka服务器的微服务名
cloud:
config:
server:
git:
uri: git@gitee.com:tinccccccc/spring-cloud-config.git # gitee上面的仓库名称
# 搜索目录
search-paths:
- springcloud-config
# 读取的分支
label: master
# RabbitMq相关配置
rabbitmq:
host: 114.55.56.149
port: 5672
username: admin
password: 123456
# rabbitmq 相关配置,暴露bus刷新配置的端点
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
然后我们需要修改ConfigClient的相关信息,首先Pom增加依赖:
org.springframework.cloud
spring-cloud-starter-bus-amqp
增加ConfigClient端的yml配置:
spring:
application:
name: config-client # 注册进Eureka服务器的微服务名
cloud:
config:
label: master # 分支名称
name: config # 配置文件名称
profile: dev # 读取后缀名称 上述三个综合:master分支上config-dev.yml的配置文件被读取http://localhost:3344/master/config-dev.yml
uri: http://localhost:3344
rabbitmq:
host: 114.55.56.149
port: 5672
username: admin
password: 123456
ConfigClient3366端也是和ConfigClient3355做一样的修改。
然后我们修改gitee上的配置信息。然后通过命令发送bus-refresh(该命令即为我们在ConfigServer3344中配置的命令)
# rabbitmq 相关配置,暴露bus刷新配置的端点
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
测试:在各个ConfigClient客户端没有重启的情况下,就可以获取到gitee上最新的配置信息。解决了一次请求服务端,所有客户端都自动刷新的需需求,即SpringCloudBus动态刷新全局广播。
那么如何实现定点通知呢,比如只通知客户端3355不通知客户端3366。我们只需要修改发送的请求。即:http://localhost:3344/actuator/bus-refresh/config-client:3355"(这里的config-client:3355 是微服务名+端口号)即可实现3355动态刷新了,而3366没有刷新。



