原文地址:https://www.jianshu.com/p/4b8cc505a69b
rabbitmq的shovel功能
很多时候线上rabbitmq的队列会出现消息堆积,消息堆积的时候可以通过后期优化代码逻辑或者增加消费者的实例数去解决。
但是后期的代码优化在面临紧急情况时总归是“远水解不了近渴”,并且有些业务场景也井非可以简单地通过增加消费实例而得以增强消费能力。
在一筹莫展之时,不如试一下 Shovel 。当某个队列中的消息堆积严重时,比如超过某个设定的阑值,就可以通过 Shovel 将队列中的消息移交给另一个集群。
1、shovel是什么
Shovel 够可靠、持续地从一个 Broker 中的队列(作为源端 ,即 source )拉取数据并转发至另一个 Broker 中的交换器(作为目的端,即 destination )。
作为源端的队列和作为目的端的交换器可以同时位于同一个 Broker ,也可以位于不同的Broker 上。
Shovel 可以翻译为“铲子”,是一种比较形象的比喻,这个“铲子”可以将消息从一方“挖到”另一方。
2、shovel的原理
如上图
shovel就是通过amqp协议,把一个实例队列里面的消息转发到另外一个实例的交换机。
message通过exchange1->queue1->exchange2->queue2的路径达到。
3、shovel的使用
3.1. 创建两个rabbitmq的实例
在机器1执行命令
docker run -d --hostname rabbit1 --net=host --name myrabbit1 rabbitmq:3.6.15-management
在机器1执行命令
docker run -d --hostname rabbit3 --net=host --name myrabbit3 rabbitmq:3.6.15-management
3.2. 开启插件
在机器3执行命令进入容器
docker exec -it myrabbit3 /bin/bash
执行命令开启插件
rabbitmq-plugins enable rabbitmq_shovel_managementt
开启后,控制台会多两个菜单
3.3. 新建队列和交换机
在机器1新建eujian.queue1队列、eujian.exchange1交换机、和他们之间的绑定。
这里使用命令行去新建(可以用管理后台自行新建)
docker exec -it myrabbit1 /bin/bash
进入docker 容器
rabbitmqctl eval 'rabbit_amqqueue:declare({resource, <<"/">>, queue, <<"eujian.queue1">>}, true, false, [], none).'
rabbitmqctl eval 'rabbit_exchange:declare({resource, <<"/">>, exchange, <<"eujian.exchange1">>}, fanout, true, false, false, []).'
rabbitmqctl eval 'rabbit_binding:add({binding, {resource, <<"/">>, exchange, <<"eujian.exchange1">>}, <<"*">>, {resource, <<"/">>, queue, <<"eujian.queue1">>}, []}).'
在机器3新建eujian.queue3队列、eujian.exchange3交换机、和他们之间的绑定。
这里使用命令行去新建(可以用管理后台自行新建)
rabbitmqctl eval 'rabbit_amqqueue:declare({resource, <<"/">>, queue, <<"eujian.queue3">>}, true, false, [], none).'
rabbitmqctl eval 'rabbit_exchange:declare({resource, <<"/">>, exchange, <<"eujian.exchange3">>}, fanout, true, false, false, []).'
rabbitmqctl eval 'rabbit_binding:add({binding, {resource, <<"/">>, exchange, <<"eujian.exchange3">>}, <<"*">>, {resource, <<"/">>, queue, <<"eujian.queue3">>}, []}).'
3.4. 新建shovel
在机器3执行命令创建shovel
rabbitmqctl set_parameter shovel myshovel '{"src-uri":"amqp://guest:guest@192.168.2.139:5672","src-queue":"eujian.queue1","dest-uri":"amqp://guest:guest@192.168.2.138:5672","dest-exchange":"eujian.exchange3","src-exchange-key":"*","prefetch-count":64,"reconnect-delay":5,"publish-properties":[],"add-forward-headers":true,"ack-mode":"on-confirm"}'
这里ip改成自己的rabbitmq实例ip。
这里可以用管理台页面去创建shovel。
3.5. 验证
在机器1的rabbitmq的eujian.exchange1发送消息。
然后看到机器3的eujian.queue3