16.springcloud bus消息总线
Bus支持两种消息代理:RabbitMQ和Kafka
什么是总线
在微服务架构的系统中,通常会使用轻量级的消息代理来构建一个共用的消息主题,并让系统中所有的微服务实例都连接上了,
由于该主题中产生的消息会被所有实例监听和消费,所以称它为消息总线。
在总线上的各个实例,都可以方便的广播一些需要让其他连接在该主题上的实例都知道的消息。
基本原理
ConfigClient实例都监听MQ中同一个topic(默认是springCloudBus)。当一个服务刷新数据时,他会把这个消息放入Topic中,
这样其他监听同一个topic的服务就能得到通知,然后去更新自身的配置。
步骤:
1.安装rabbitMq
1.[root@bogon ~]# docker search rabbitmq
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/rabbitmq RabbitMQ is an open source multi-protocol ... 3872 [OK]
docker.io docker.io/tutum/rabbitmq Base docker image to run a RabbitMQ server 22
docker.io docker.io/kbudde/rabbitmq-exporter rabbitmq_exporter for prometheus 15 [OK]
···
2.[root@bogon ~]# docker pull rabbitmq
Using default tag: latest
Trying to pull repository docker.io/library/rabbitmq ...
latest: Pulling from docker.io/library/rabbitmq
3.docker run -d --name rabbit -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -p 15672:15672 -p 5672:5672 -p 25672:25672 -p 61613:61613 -p 1883:1883 rabbitmq:management
说明
1.命令中的【RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin】是web管理平台的用户名和密码
2.【 -p 15672:15672】 是控制平台docker映射到系统的对应端口
3.【 -p 5672:5672】 是应用程序的访问端口
页面访问:http://192.168.2.129:15672/
登录:admin/admin
出现rabbitmq的web页面
1.Bus动态刷新广播通知
bus的设计思想:
1.利用消息总线触发一个客户端/bus/refresh,而刷新所有客户端的配置。
2.利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,而刷新所有客户端的配置(更合适)
第一种设计思想(触发客户端/bus/refresh,从而刷新所有客户端配置)不合适的原因:
1.破坏了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责。
2.破坏了微服务各节点的对等性。
3.有一定的局限性。例如微服务在迁移时,他的网络地址常常会发生变化,此时如果想要做到自动刷新,那么就会增加更多的修改。
代码更改:bus(服务总线)和config(服务配置中心)经常搭配使用
1.在config服务端上的更改
1.1. pom文件更改:
bus amqp队列支持的jar
<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>
1.2 application.yml中的配置
server:
port: 3355
spring:
application:
name: cloud-config
cloud:
config:
server:
git:
search-paths: 吴孟达/spring-clooud
uri: https://gitee.com/wu-mengda/spring-clooud.git
default-label: master
重点1:spring rabbitmq的配置,主题不配置默认是:springCloudBus
rabbitmq:
host: 192.168.2.129
port: 5672
username: admin
password: admin
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
#单机版
defaultZone: http://eureka7001:7001/eureka,http://eureka7002:7002/eureka
instance:
instance-id: cloud-config
prefer-ip-address: true
# Eureka客户端向服务心跳的时间间隔是1s,默认是30秒
lease-renewal-interval-in-seconds: 1
重点2:配置暴露的端点-->这和后面发送的post请求路径有关系,必须是bus-refresh,其他的不行,已测试
management:
endpoints:
web:
exposure:
include: "bus-refresh"
2.在config客户端的配置:
1.1. pom文件更改:
bus amqp队列支持的jar
<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. bootstrap.yml(config客户端的配置文件是bootstrap.yml)的配置
server:
port: 3344
spring:
application:
name: cloud-config-client
cloud:
#config客户端配置
config:
label: master #分支名称
name: config #配置文件名称
profile: dev #读取后缀名称 上述三个综合:master分支上的config-dev.yml配置文件被读取
#加上路径uri后:http://localhost:3355/master/config-dev.yml
uri: http://localhost:3355
#重点1:增加rabbitmq的配置,使config服务端和config客户端连接同一一个rabbitmq,并订阅同一主题:默认是springCloudBus
rabbitmq:
host: 192.168.2.129
port: 5672
username: admin
password: admin
eureka:
client:
#表示是否将自己注册进EurekaServer默认为true。
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetchRegistry: true
service-url:
#单机版
defaultZone: http://eureka7001:7001/eureka,http://eureka7002:7002/eureka
instance:
instance-id: cloud-config-client
prefer-ip-address: true
重点2:不变,还是暴露所有端点
#暴露监控端点
management:
endpoints:
web:
exposure:
include: "*"
2.3 控制层代码,测试取到外部配置文件的值
@RestController
//加上RefreshScope注解,会自动刷新获取的配置文件内容configInfo
@RefreshScope
public class ConfigController {
/*
如果可以打印出config.info的内容,则说明,配置加载成功!
*/
@Value("${config.info}")
private String configInfo;
@GetMapping("/getConfigInfo")
public String getConfigInfo(){
return configInfo;
}
}
3.可以建立多个相同的config客户端模拟多场景微服务
4.很重要的一步,不能忘,要不,自动刷新配置不生效,需要向config服务端发送一个post请求:http://localhost:3355/actuator/bus-refresh
4.1 注意点:必须是往config的服务端发送post请求,因为采用的是设计思想2(利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,而刷新所有客户端的配置)
4.2 路径必须是:http://localhost:3355/actuator/bus-refresh
5.这时config服务端和客户端的配置文件都达到最新!
重点:无需重启各微服务,达到配置文件动态刷新的效果!
达到了一次修改,广播通知,处处生效!
2.springcloud bus动态刷新定点通知
场景:通知某些微服务(即让微服务使用新配置),其他的仍使用老配置
发送post请求的格式发生变化:
http://config服务端ip:服务端端口/actuator/bus-refresh/需要通知的客户端名称信息
如:
http://localhost:3355/actuator/bus-refresh/cloud-config-client:3344 (组成:客户端名称(spring.application.name的值):端口号)
刷新哪个发送哪个