目录
概述
上一章的加深和扩充,一言以蔽之。分布式自动刷新配置功能:Spring Cloud Bus + Spring Cloud Config
可以实现配置的动态刷新。
是什么
Spring Cloud Bus
是用来将分布式系统的节点与轻量级消息系统链接起来的框架,它整合了java
事件处理机制和消息中间件的功能
Bus
支持两种消息代理:RabbitMQ
和Kafka
能干嘛
Spring Cloud Bus
能管理和传播分布式系统间的消息,就像一个分布式执行器,可用于广播状态更新,事件推送等,也可以作为微服务间的通信通道。
为何被称为总线
总线:在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有微服务实例都连接上来。由于该主题中产生的消息会被所有实例监听和消费,所以称为总线。在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。
原理:ConfigClient
实例都监听MQ
中同一个topic
(默认是SpringCloudBus
)。当一个服务刷新数据的时候,它会把这个信息放入到Topic中,这样其他监听同一个Topic的服务就能得到通知,然后去更新自身配置
RabbitMQ环境配置
服务器上安装docker
:https://blog.csdn.net/weixin_42412601/article/details/89956486
然后安装rabbitmq
:https://www.cnblogs.com/angelyan/p/11218260.html
访问页面:http://192.168.63.131:15672/#/
user password
SpringCloud Bus动态刷新全局广播
再增加一个配置中心客户端
cloud-config-client-3366子模块,与3355一致,只有端口不一致。
3355创建过程:https://blog.csdn.net/weixin_42412601/article/details/107141389
下的Config客户端配置与测试。
3366的controller稍微改改:
//将配置信息以rest风格暴露
@RestController
@RefreshScope
public class ConfigClientController {
@Value("${server.port}")
private String port;
@Value("${spring.application.name}")
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo(){
return configInfo+" "+port;
}
}
设计思想
- 利用消息总线触发一个客户端
/bus/refresh
,而刷新所有客户端的配置
- 利用消息总线触发一个服务端
ConfigServer
的/bus/refresh
端点,而刷新所有客户端的配置(更加推荐)
图二的架构显然更加合适,图一不适合的原因如下: - 打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新职责
- 破坏了微服务各节点的对等性
- 有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改
Bus动态刷新全局广播配置实现
基于第二种设计思想实现。
给cloud-config-center-3344配置中心服务端添加消息总线支持
注意是配置中心服务端!
pom
:
<!--消息总线rabbitmq支持-->
<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>
yml
:添加rabbitmq
配置以及暴露相关端点
完整配置:
添加rabbitmq
配置,注意这里的这个配置是在spring
下面,与cloud
同级
server:
port: 3344
spring:
application:
name: cloud-config-center
cloud:
config:
server:
git:
uri: https://github.com/lzhharvey/springcloud-config.git
search-paths:
- springcloud-config #去这个springcloud-config目录下找配置
label: master #读取的分支
#rabbit相关配置
rabbitmq:
host: 192.168.63.131
port: 5672
username: user
password: password
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
#暴露bus刷新配置的端点
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
给cloud-config-center-3355客户端添加消息总线支持
注意是配置中心客户端!
pom:
<!--消息总线rabbitmq支持-->
<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>
yml
:
server:
port: 3355
spring:
application:
name: config-client
cloud:
config:
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称
uri: http://localhost:3344 #配置中心读取
#以上配置相当于,master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
#rabbit相关配置
rabbitmq:
host: 192.168.63.131
port: 5672
username: user
password: password
eureka:
client:
service-url:
defaultZone: http://eureka7001.com:7001/eureka, http://eureka7002.com:7002/eureka
#暴露监控端口
management:
endpoints:
web:
exposure:
include: "*"
给cloud-config-center-3366客户端添加消息总线支持
同上
测试
启动Eureka
集群,启动配置中心服务端3344
,启动两个客户端。
1.先用服务端直接访问github
上配置试试:http://localhost:3344/config-dev.properties
spring.application.name: dev11
2.两个客户端访问获取服务端配置试试:
http://localhost:3355/configInfo
http://localhost:3366/configInfo
3.修改github
配置文件配置
4.按照我们的设计思想。现在只需刷新我们的/bus/refresh
3344,也就是配置中心服务端,刷新它,从而刷新所有客户端的配置
C:\Users\Administrator>curl -X POST "http://127.0.0.1:3344/actuator/bus-refresh"
5.先用服务端直接访问github
上配置试试:http://localhost:3344/config-dev.properties
这个直连github
没啥疑问,主要看两个客户端动态刷新没有:
成功了!
通过Bus
动态刷新全局广播配置,就可以解决如果多个客户端,修改了配置,一个一个去刷新的操作,现在只需要刷新配置中心服务端即可!
印证原理
之前说了原理 :在上面
去到rabbitmq
上看到,所谓的SpringCloud Bus
消息总线,其实就是一个topic
而已。配置中心的客户端都去订阅它,当配置中心服务端刷新数据的时候,服务端会把信息放到消息总线这个topic
中,然后总线将这个消息广播到所有订阅它的客户端。
SpringCloud Bus动态刷新定点通知
不想全部通知,只想定点通知。只通知3355,不通知3366。
简单一句话:指定具体某一个实例生效而不是全部。
公式:http://localhost:配置中心的端口号/actuator/bus-refresh/{destination}
例如:只刷新3355,不刷新3366
curl -X POST "http://localhost:3344/actuator/bus-refresh/config-client:3355"