转载自: https://yq.aliyun.com/articles/42383?spm=a2c4e.11153940.0.0.666f202bTDO7gA
从之前的两篇文章《 【原创】RabbitMQ 之 Shovel(翻译) 》和《 【原创】RabbitMQ 之 Dynamic Shovel(翻译) 》中,我们已经知道 shovel 插件的使用存在 static 和 dynamic 两种形式,其主要差异如下
在了解了 shovel 的基本功能之后,下一个需要考虑的问题就是 shovel 的使用场景。相关的几个问题总结如下: 1.为什么需要使用 shovel 插件? 答:当业务需要可靠且连续地将消息从一个 broker 的 queue 里搬运(转发)到另一个 broker 的 exchange 时(最终达到某个 queue 里 )使用;作为 source 的 queue 和作为 destination 的 exchange 可以位于同一个 broker 上(通常要求处于不同的 vhost 下),也可以位于不同的 broker 上。 2.使用 shovel 插件的好处? 答:shovel 基于 RabbitMQ 的 Erlang 客户端实现,且作为 built-in 插件被使用,故可以随 broker 的启动而自动启动;shovel 具有松耦合特性:通过该插件可以在分属不同管理域下的 broker 或 cluster 之间进行消息的搬运;shovel 具有 WAN 友好特性:基于 AMQP 0-9-1 协议实现,并设计成能够保证在不稳定网络场景下不丢失消息;shovel 具有高度可定制性:允许在 shovel 建立连接后,立即执行指定的 AMQP 方法进行定制化操作(例如声明 queue 的动作); 3.shovel 与 cluster 的结合问题 答:如果每个 shovel 均指定了属于源集群或目的集群中的多个 source URI 或 destination URI ,那么当 shovel 遇到节点失效时,就可以进行失效转移操作;对于 dynamic shovel 来说,其定义信息会出现在使能了 shovel 插件的、目标集群中的所有节点上(即所有节点都能获取到 shovel 的定义信息),而每一个 shovel 仅会在集群中的某一个节点上启动(任意一个),并在该节点失效后,转移到另外的节点上去;对于 static shovel 来说,需要在使能了 shovel 插件的、目标集群中的所有节点的配置文件中添加相应的定义信息,同样的,每一个 shovel 仅会在集群中的某一个节点上启动,并在该节点失效后转移到另外的节点上去。 下面给出 shovel 使用场景示例图(取自 《RabbitMQ in Action》) (大概意思描述,下同)在两个地理位置相距较远的地方布置了两个 RabbitMQ 节点,其中 Goleta 节点用于负责大部分订单的处理,而 Carpinteria 节点用于解决 Goleta 节点达到一个负荷后的、额外订单的处理。该场景属于基于 WAN 的互联,所以无法使用 RabbitMQ 的集群功能; 在未使用 shovel 功能前,只能通过同时将订单发往两地的方式进行处理,在这种场景下,最大延迟取决于较远的一端;并且可能会对业务提出变更要求; 在使用了 shovel 插件后,模型变成了近端同步确认,远端异步确认的方式,大大提高了订单确认速度,并且还能保证可靠性; 最终的内部结构图如上图所示。 一句话总结:shovel 适用于需要对资源请求(订单)快速作出相应的场景,能够有效利用跨 WAN 的其他 broker 或 cluster 一起进行请求的处理(订单处理)。 针对 static 和 dynamic 两种配置的 shovel 的实验【static shovel】首先按照《RabbitMQ in Action》中的示例进行配置(调整了监听端口,以及 user 和 password ) 此时在 Web UI 上会看到如下错误信息 或者 这两个状态在不停的切换,表明 RabbitMQ 内部在不断重新尝试建立 shovel 连接; 通过日志可以看出,问题出现在 shovel 插件建立 AMQP 连接过程的握手节点,而错误原因为“ access to vhost '', refused by user 'dev' ”。说明 vhost 的指定有错误。通过抓包内容同样可以确认这一点。重新调整配置文件如下 上图中的红框位置为增加的内容,其中 %2F 代表的就是 vhost "/" ,此处需要进行转义使用。 变更配置后,重启相应的 broker ,此时可以看到(source broker) (destination broker) 可以看到 shovel 已经正常运行了,查看此时的网络连接情况如下(注:source broker 在 81.111 上,destination broker 在 80.111 上)
[root@Betty rabbitmq]# netstat -natp|grep 6672tcp 0 0 172.16.81.111:36489 172.16.81.111:6672 ESTABLISHED 12739/beam.smp -- shovel 作为 consumer 从 source broker 上进行消费的 TCP 连接tcp 0 0 172.16.81.111:35203 172.16.80.111:6672 ESTABLISHED 12739/beam.smp -- shovel 作为 producer 向 destination broker 发送消息的 TCP 连接tcp 0 0 :::6672 :::* LISTEN 12739/beam.smptcp 0 0 ::ffff:172.16.81.111:6672 ::ffff:172.16.81.111:36489 ESTABLISHED 12739/beam.smp [root@Betty rabbitmq]#
到此,静态 shovel 的基本使用已经摸的比较清楚了~~ 【dynamic shovel】 有了 static shovel 作为基础,可以快速掌握 dynamic shovel 的使用情况。 参考官方文档 《 【原创】RabbitMQ 之 Dynamic Shovel(翻译) 》 中提到的简单示例内容进行配置,会遇到如下错误 简单调整后的正确输出如下 最后的总结: