RabbitMQ–扩展–09–Shovel
1、Shovel原理
- Shovel插件只提供数据迁移的作用,非复制。举例:C中心rabbitmq产生一条数据A,DR中心rabbitmq部署了Shovel插件后,会去C中心消费数据A,最终C中心rabbitmq没有数据A,DR中心rabbitmq有数据A。
- Shovel能够可靠、持续地从一个Broker中的队列(作为源端,即source)拉取数据并转发至另一个Broker中的交换器(作为目的端,即destination)。
- 作为源端的队列和作为目的端的交换器可以同时位于同一个Broker,也可以位于不同的Broker上。
- Shovel行为就像优秀的客户端应用程序能够负责连接源和目的地、负责消息的读写及负责连接失败问题的处理。
1.1、优点
- 松耦合,解决不同Broker、集群、用户、vhost、MQ和Erlang版本的消息移动
- 支持广域网,可以容忍糟糕的网络
- 能保证消息的可靠性,高度定制,当Shovel成功连接后,可以配置。
2、Shovel的工作原理
若在配置Shovel link时设置了add_forward_headers参数为true,则最后消息会有特殊headers属性标记。
通常源为队列,目的为交换器,但是,也可以源为队列,目的为队列。实际也是由交换器转发,只不过这个交换器是默认交换器。
配置交换器做为源也是可行的。实际上会在源端自动新建一个队列,消息先存在这个队列,再被Shovel移走。
源和目的端的交换器和队列都可以在建立Shovel之后再创建。Shovel可以为源端或目的端配置多个Broker地址,这样可以在一个连接失败后随机挑选其他地址建立连接。
3、环境准备
3.1、机器
服务器地址 | 端口 | 备注 |
---|---|---|
192.168.187.89 | 15672 | 容器名称:rabbitmq,上游 |
192.168.187.89 | 15673 | 容器名称:rabbitmq2,下游 |
3.2、创建对应的rabbitmq容器
# 创建对应的rabbitmq容器
# 容器名称:rabbitmq
docker run -d --name rabbitmq -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -p 15672:15672 -p 5672:5672 --restart=always rabbitmq:3.12.14-management-alpine
# 容器名称:rabbitmq2
docker run -d --name rabbitmq2 -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -p 15673:15672 -p 5673:5672 --restart=always rabbitmq:3.12.14-management-alpine
3.1.2、创建用户
# 添加用户 bpm,密码 123456
docker exec rabbitmq rabbitmqctl add_user bpm 123456
# 给bpm用户分配 administrator角色
docker exec rabbitmq rabbitmqctl set_user_tags bpm administrator
# 设置 分区为/,拥有对所有资源的 读写配置权限
docker exec rabbitmq rabbitmqctl set_permissions -p / bpm ".*" ".*" ".*"
# 添加用户 bpm,密码 123456
docker exec rabbitmq2 rabbitmqctl add_user bpm 123456
# 给bpm用户分配 administrator角色
docker exec rabbitmq2 rabbitmqctl set_user_tags bpm administrator
# 设置 分区为/,拥有对所有资源的 读写配置权限
docker exec rabbitmq2 rabbitmqctl set_permissions -p / bpm ".*" ".*" ".*"
3.2、开启shovel插件
# 容器名称:rabbitmq
docker exec rabbitmq rabbitmq-plugins enable rabbitmq_shovel_management
# 容器名称:rabbitmq2
docker exec rabbitmq2 rabbitmq-plugins enable rabbitmq_shovel_management
3.3、新建队列,交换机,和他们之间的绑定
2个容器都要创建
# 容器:rabbitmq1,rabbitmq2
eujian.queue
eujian.exchange
eujian.routKey
4、Shovel的构建
Shovel插件只提供数据迁移的作用,非复制。举例:C中心rabbitmq产生一条数据A,DR中心rabbitmq部署了Shovel插件后,会去C中心消费数据A,最终C中心rabbitmq没有数据A,DR中心rabbitmq有数据A。
4.1、原理图
4.2、下游rabbitmq2 新增shovel
# 名称:队列同步到交换机
shovel-queue-to-exchange
# 上游rabbitmq
amqp://bpm:123456@192.168.187.89:5672
# 下游rabbitmq
amqp://bpm:123456@192.168.187.89:5673
# 队列、交互机、路由键
eujian.queue
eujian.exchange
eujian.routKey
4.3、测试
在上游rabbitmq1的交换机上发送一条消息。
5、消息堆积的治理
5.1、场景
单个队列中堆积10万条消息不会有丝毫影响,但超过1千万时,将引起严重问题,如内存、磁盘告警、connection阻塞等。
可以使用Shovel,当某个队列消息堆积严重时,可以使用Shovel将队列中消息移交给另一个集群
5.2、处理
- 当检测到集群cluster1中队列queue1中有严重消息堆积,如通过/api/queues/vhost/name获取消息个数messages超过2千万或者消息占用大小messages_bytes超过10GB时,启用shovel1将queue1中消息转发至备份集群cluster2中队列queue2
- 当检测到queue1中消息个数低于1百万或者消息大小低于1GB时,停止shovel1,让原本队列消化剩余堆积
- 当检测到queue1消息个数低于10万个或占用大小低于100MB时,开启shovel2将queue2队列中暂存的消息返还队列queue1
- 当检测到queue1消息个数超过1百万,或消息占用高于1GB时,将shovel2停掉。
6、总结
6.1、Shovel
Shovel插件只提供数据迁移的作用,非复制。举例:C中心rabbitmq产生一条数据A,DR中心rabbitmq部署了Shovel插件后,会去C中心消费数据A,最终C中心rabbitmq没有数据A,DR中心rabbitmq有数据A。
6.2、灾备双活架构
数据库:主机房、灾备机房的应用都连接主机房的数据集
rabbimq:主机房、灾备机房的应用都连自己机房的rabbitmq,因为是Shovel,当灾备机房消费消息的时候,会将主机房的消息移动到灾备机房。所以消息是没有重复消费的。因为又连接同一个数据库,所以数据是一致的