1. 概述
Spring Cloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架,整合了Java的事件处理机制和消息中间件的功能,目前支持RabbitMQ和Kafka两种消息中间件。其功能是管理和传播分布式系统间的消息,用于广播状态更改、事件推送和微服务间通信通道,配合Spring Cloud Config使用可以实现配置的动态刷新,其实现原理是Config Client实例都监听MQ中同一个topic,当一个服务刷新数据的时候,会把这个信息放入到Topic中,这样其他监听同一个topic的服务就能得到通知,然后去更新自身的配置。
总线:在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来,由于该主题中产生的消息会被所有实体监听和消费,所以称之为消息总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息
Spring Cloud Bus配合Spring Cloud Config实现配置动态刷新需要借助MQ,本文使用RabbitMQ,需要提前搭建好RabbitMQ开发环境,有需要了解如何安装RabbitMQ的小伙伴可以访问阿里云服务器CentOS8安装RabbitMQ
2. 搭建Bus Server服务
2.1. 引入核心依赖
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.2. 编写主启动类
@EnableConfigServer
@SpringBootApplication
public class BusServerApplication {
public static void main(String[] args) {
SpringApplication.run(BusServerApplication.class, args);
}
}
2.3. 编写application.yml配置
server:
port: 8822
spring:
application:
name: cloud-bus-server
cloud:
config:
server:
git:
uri: https://github.com/xxxx/springcloud-config.git #git仓库地址
default-label: master #读取分支
search-paths:
- springcloud-config #文件目录
rabbitmq:
host: xx.xx.xxx.xxx
port: 5672
username: admin
password: 123456
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
3. 搭建Bus Client服务
分别新建两个Bus Client微服务
3.1. 引入核心依赖
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
3.2. 编写主启动类
@SpringBootApplication
public class BusClientApplication {
public static void main(String[] args) {
SpringApplication.run(BusClientApplication.class, args);
}
}
3.3. 编写bootstrap.yml配置
server:
port: 8823/8824
spring:
application:
name: cloud-bus-client
cloud:
config:
label: master
name: config
profile: prod
discovery:
enabled: true #开启配置服务的自动发现机制
service-id: cloud-bus-server
rabbitmq:
host: xx.xx.xxx.xxx
port: 5672
username: admin
password: 123456
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
management:
endpoints:
web:
exposure:
include: '*'
3.4. 编写业务接口类
@RefreshScope
@RestController
public class BusClientController {
@Value("${server.port}")
private String serverPort;
@Value("${config.info}")
private String configInfo;
@GetMapping("/getConfigInfo")
public String getConfigInfo() {
return "serverPort:" + serverPort + "\t\n\n configInfo:" + configInfo;
}
}
4. 验证
依次启动Eureka Server、Bus Server和两个Bus Client微服务,在浏览器地址栏输入http://localhost:8822/master/config-prod.yml
在浏览器地址栏输入http://localhost:8823/getConfigInfo和http://localhost:8824/getConfigInfo
修改git上版本为2,再次访问http://localhost:8822/master/config-prod.yml、http://localhost:8823/getConfigInfo和http://localhost:8824/getConfigInfo三个地址,发现Bus Server服务可以立即获取到最新配置,两个Bus Client服务都不能获取到最新配置
4.1. 全局刷新
发送POST请求curl -X POST “http://localhost:8822/actuator/bus-refresh”
再次访问http://localhost:8823/getConfigInfo和http://localhost:8824/getConfigInfo
4.2. 定点刷新
只指定具体某一个实例刷新配置,其他实例不需要刷新配置
发起POST请求curl -X POST “http://localhost:8822/actuator/bus-refresh/cloud-bus-client:8823”
再次访问http://localhost:8823/getConfigInfo和http://localhost:8824/getConfigInfo