SpringCloud Bus动态刷新全局广播
SpringCloud
Spring Cloud Bus配合Spring Cloud Config使用可以实现配置的动态刷新,通知一处,处处生效。而不用一个一个去通知。
Spring Cloud Bus是消息总线,广播通知都可以集成,不止用于实现配置的动态刷新。
简介
分布式自动刷新配置功能
SpringCloud Bus是用来将分布式系统的节点与轻量级消息连接起来的框架,它整合了Java的事件处理机制和消息中间件的功能。
SpringCloud Bus目前支持RabbitMQ和Kafka。
什么是总线:
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由该主题中产生的消息会所有的实例监听和消费,所以称它为消息总线,在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的商息。
ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus).当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其它监听同一Topic们服务就能得到通知,然后去更新自身的配置。
https://www.bilibilicom/ideo/avss9767007from=search&seid=15010075915728605208
设计思想
2种:
一、利用消息总线触发一个客户端/bus/refesh,而刷新所有客户端的配置
二、利用消息总线触发一个服务端ConfigServer的/bus/refesh端点,而刷新所有客户端的配置
显然第二种方式更加适合,第一种不适合的原因如下:
- 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责
- 打破了微服务各节点的对等性
- 有一定的局限性.例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做自动刷新,那就会增加更多的修改
实现配置的动态刷新
这里是运用rabbitmq消息中间件的,先搭建rabbitmq环境
客户端
创建多个客户端微服务,测试范例:
依赖配置:
<!-- bus -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!-- config -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
bootstrap.yml
server:
port: 3366
spring:
# application:
# name: config-client3366
cloud:
config:
label: master # 分支名称
name: application # 配置文件名称,可自定义,最好application/config
profile: dev # 文件中的dev profile内容,上述三个综合,为master分支上的application.yml的配置文件中的dev内容被读取http://localhost:3344/application/dev/master
uri: http://localhost:3344 #配置中心的地址
rabbitmq: #rabbitmq相关配置,15672是web管理端口,5672是mq访问端口
port: 5672
host: 192.168.169.135
username: guest
password: guest
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
management:
endpoints:
web:
exposure:
include: "*"
controller
/**
*
* @author zzyy
* @version 1.0
* @create 2020/03/06
*/
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${spring.application.name}")
private String applicationName;
@Value("${server.port}")
private String serverPort;
@GetMapping("/applicationName")
public String getApplicationName(){
return serverPort + ": " + applicationName;
}
}
服务端
依赖配置:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<!-- config server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
application.yml
server:
port: 3344
spring:
application:
name: cloud-config-center
cloud:
config:
server:
git:
uri: https://github.com/wzq-55552/springcloud-config.git #配置远程的仓库地址springcloud-config
search-paths:
- springcloud-config
label: master #进到仓库的主分支
rabbitmq:
host: 192.168.169.135
port: 5672
username: guest
password: guest
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
# 暴露bus刷新配置的端点,bus-refresh
management:
endpoints:
web:
exposure:
include: "bus-refresh"
启动类加入注解@EnableConfigServer
测试
微服务全部启动
修改github上的配置文件内容:
spring:
profiles: dev #开发环境
application:
name: github-dev-config-bus-application-name-2
服务端可以同步改变,但是客户端得重新启动才可以同步修改,默认客户端是无法立即生效的,查看controller:
这时运维人员执行(3344是配置中心的端口):curl -X POST "http://localhost:3344/actuator/bus-refresh"可以cmd执行测试,这里我使用postman:
http://localhost:3344/actuator/bus-refresh 必须是post请求
再一次查看所有客户端controller(返回配置信息):
查看rabbitmq的交换机,这时默认有了springCloudBus交换机:
动态刷新定点通知
不想全部通知,只想定点通知,只通知3355,不通知3366。
指定具体一个实例生效而不是全部
http://localhost:配置中心端口号/actuator/bus-refresh/{destination}
/bus/refresh请求不再发送到具体的服务实例上,而是发给config server并通过destination参数类指定需要重新配置的服务或实例
curl -X POST “http://localhost:3344/actuator/bus-refresh/微服务名:微服务端口”
后面格式是微服务名:微服务端口
测试:
修改测试客户端:
@Value("${server.port}")
private String serverPort;
@Value("${spring.config.info}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo(){
return serverPort + ": " + configInfo;
}
微服务配置修改为获取test环境,全部启动
github修改内容,初始test:
postman 发送post请求http://localhost:3344/actuator/bus-refresh/config-client3355:3355 修改3355微服务的配置:
定点通知只能修改一个微服务的配置