SpringCloud Bus消息总线

1、介绍

①概念

人话:不用一个一个服务去post。一次post后,各个服务通过bus都能获取post的信息去更新配置。

即将N次向client的post,改为了一次post(向client或center)

在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,让系统里面所有的微服务都连接上来,由于该主题中产生的消息会被所有实例监听和消费,所以称他为消息总线。

在总线上的各个实例,都可以方便地广播一些需要让其他连接在该主题上的实例都知道的消息。

②原理

ConfigCilent实例都监听MQ中一个Topic,一个服务刷新数据时候,会放入Topic,这样其他监听同一个Topic的服务就能知道了,然后可以更新自己。

不就是消息队列嘛,数据刷新的时候会放入消息队列,Client监听消息队列,然后通过消息获得通知,更新自己的配置

③设计思路/选择

一.通过Client传达

通过消息总线触发一个客户端/bus/refresh,刷新所有客户端的配置

image-20230118194935844

二.通过ConfigServer传达(使用这个)

利用消息总线,触发一个服务端ConfigServer的/bus/refresh端点,从而刷新所有的客户端配置

image-20230118195014558

三.选择通过设计二搭建的原因

  1. 一打破了微服务的职责单一性,因为微服务本身是业务模块,不应该承担配置刷新职责
  2. 破坏微服务之间的对等性
  3. 在服务迁移的时候,地址会变化,这时候需要很多更改

2、搭建环境

①搭建RabbitMQ

拉取rabbitMQ的镜像文件:

docker pull rabbitmq:3.8.3-management

image-20230118193316210

运行rabbitmq:

docker run -d -p 5672:5672 -p 15672:15672 --name myRabbitMQ 容器id

image-20230118193404775

访问可视化界面15672端口:

用户名密码都为guest

image-20230118193647876

image-20230118193714653

②搭建另一个Cient

新建项目cloud-config-client-3366

pom.xml:

<dependencies>
<!--config server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--eureka client(通过微服务名实现动态路由)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

bootstrap.yml:

server:
port: 3366
spring:
application:
name: config-client
cloud:
config: #config客户端配置
label: master #分支名称
name: config #配置文件名称 这三个综合:master分支上的config-dev.yml的配置文件
profile: dev #读取后缀名称 被读取到http://config-3344.com:3344/master/config/dev
uri: http://localhost:3344 #配置中心地址
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka #服务注册到的eureka地址
#暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"

启动类:

@EnableEurekaClient
@SpringBootApplication
public class ConfigClientMain3366 {
public static void main(String[] args) {
SpringApplication.run(ConfigClientMain3366.class, args);
}
}

Controller:

@RestController
@RefreshScope
public class ConfigClientController {
@Value("${config.info}") //spring的@Value注解
private String configInfo;
@GetMapping("/configInfo")
public String getConfigInfo(){
return configInfo;
}
}

3、全局广播

①在ConfigCenter上添加BUS支持

添加BUS-rabbitmq依赖:

image-20230118195949690

<!--添加消息总线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:

image-20230118200307840

spring:
application:
name: cloud-config-center #注册进Eureka服务器的微服务名
cloud:
config:
server:
git:
uri: https://github.com/zko0/springcloud-config.git #git的仓库地址
search-paths: #搜索目录
- springcloud-config
#如果仓库为私有,需要下面的认证信息
#username: zko0 用户名
#password: xxxxxxx token
label: master #读取的分支
#RabbitMQ相关配置
rabbitmq:
host: #本机写localhost,服务器的写服务器地址
port: 5672 #客户端和RabbitMQ进行通信的端口
username: guest #默认也是guest
password: guest #默认也是guest
management:
endpoints: #暴露bus刷新配置的端点
web:
exposure:
include: 'bus-refresh'

②在Client(3355、3366)上添加BUS支持

添加bus-rabbitmq依赖:

<!--添加消息总线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:

image-20230118203601022

spring:
application:
name: config-client
cloud:
config: #config客户端配置
label: master #分支名称
name: config #配置文件名称 这三个综合:master分支上的config-dev.yml的配置文件
profile: dev #读取后缀名称 被读取到http://config-3344.com:3344/master/config/dev
uri: http://localhost:3344 #配置中心地址
rabbitmq:
host: 101.43.244.40 #本机写localhost,服务器的写服务器地址
port: 5672 #客户端和RabbitMQ进行通信的端口
username: guest #默认也是guest
password: guest #默认也是guest
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka #服务注册到的eureka地址
#暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"

③测试

启动ConfigServer3344,Clinet3355,3366,测试,正常:

image-20230118203822466

修改仓库中的config-dev配置,将version改为5

image-20230118203718743

一段时间后,Config Center动态更新配置,version更新为5,此时Client的version仍为4:

image-20230118204048550

image-20230118204104533

向Config Center发送Post请求,url为:

http://localhost:3344/actuator/bus-refresh

image-20230118204133235

此时查看Client3355,和Client3366,version都已经刷新为5,测试成功:

image-20230118204152075

4、定点通知

①概念

如果我们只想通知3355刷新配置,3366不刷新呢?

方法:

http://配置中心ip:端口号/actuator/bus-refresh/{通知目标}

/bus/refresh请求不再发送到具体的服务实例上,而是发给config server并通过destination参数类指定需要更新配置的服务或实例

如只通知3355不通知3366:

http://localhost:3344/actuator/bus-refresh/config-client:3355

②实测

修改配置文件,version为6

image-20230118214137912

Config Center的version更新为6

image-20230118214522881

发送post请求,只通知3355更新配置:

由下图可见config-client的实例和端口3355

发送请求:

http://localhost:3344/actuator/bus-refresh/config-client:3366

image-20230118214025370

image-20230118215007581

查看Client3355,和Client3366,成功:

image-20230118215047345

posted @   yikolemon  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示