在上一篇文章讲到了Config的动态刷新,由Config自己只能每次手动执行一次post请求,非常不便利,使用消息总线就可以让配置文件实现自动刷新。SpringCloud中实现了对消息总线的扩充,也就是SpringCloud Bus。Bus支持两种消息代理,RabbitMQ和Kafka。
消息总线的原理实际上十分简单,就像微信公众号一样,每次更新后,所有订阅的用户都会接收到更新。SpringCloud Bus是用来将分布式节点与轻量级消息系统连接起来的框架,可以用于广播状态更改、时间推送等,也可以当作微服务间的通信通道。
首先我们再制作一个config-client,新建项目后添加依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-configartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
然后编写配置文件application.yml
server:
port: 3366
spring:
application:
name: config-client
cloud:
# Config客户端配置
config:
label: master # 分支名称
name: config # 配置文件名称
profile: dev # 读取后缀名称
uri: http://localhost:3344 # 配置中心地址
# 服务注册Eureka地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
然后再启动类Application中添加注解@EnableEurekaClient,让其成为Eureka Client,之后写一个Controller
@RestController
@RefreshScope
public class TestController{
@Value("${text}")
String text;
@RequestMapping("/hi")
public String getText(){
return "Message: " + text;
}
}
消息总线更新信息的方式有两种:第一种是利用消息总线触发一个客户端/bus/refresh,而刷新所有客户端的配置;另一种是触发服务端的/bus/refresh,从而刷新所有的客户端配置,显然第二种方式更好。因为首先微服务有自身的功能,不应该将其添加额外的刷新配置文件的任务,打破了职责单一性。
上面我们再一次实现了一个Config Client,下面我们来将消息总线添加到Config Server和Config Client中,首先在Config Server中添加SpringCloud Bus的依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-bus-amqpartifactId>
dependency>
然后继续在Config Server中的配置文件application.yml中添加RabbitMQ的相关配置
# RabbitMQ配置
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
# 暴露Bus刷新配置端点
management:
endpoints:
web:
exposure:
include: 'bus-refresh'
下面我们修改一下Config Client,让其也使用消息总线,首先添加Bus的依赖
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-bus-amqpartifactId>
dependency>
之后在client的bootstrap.yml中添加相关配置,需要注意的是rabbitmq的配置一定要在spring下面,这里和server配置不同
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
这样即可完成消息总线的配置。在每次更新后,运维工程师只需要进行一次config server的更新,即访问http://localhost:3344/actuator/bus-refresh即可通过消息总线对所有的客户端进行更新。
有的时候我们希望通过消息总线不要通知全部的客户端,只更新一部分客户端,只需要我们更改输入的URL为
http://localhost:配置中心端口号/actuator/bus-refresh/{destination}
/bus/refresh不再发送给某一个实例,而是发送给config server并通过destination参数类指定需要更新配置的服务或实例,例如
http://localhost:3344/actuator/bus-refresh/config-client:3355
这样只会更新3355端口的config client,不会更新其他客户端的配置文件
[1] 尚硅谷SpringCloud 2020最新版