2014-11-24 92 views
7

能有人请解释发布到从属节点时是怎么回事幕后与多个节点和镜像方式队列中的RabbitMQ集群背后集群和镜像队列的行为呢?RabbitMQ的场景

从我所读到的看来,发布以外的所有操作似乎只发送给主服务器,然后主服务器将这些操作的效果广播给从服务器(这来自文档)。根据我的理解,这意味着消费者将始终使用主队列中的消息。另外,如果我向一个消息发送一个请求给一个从机,那么这个从机将通过到达主机来获取该消息来做额外的跳跃。

但是当我发布到从属节点会发生什么?此节点是否会将首先发送消息的信息发送给主服务器?

似乎有奴隶打交道时,许多附加跳,这样看来,如果你只知道主,你可以有更好的表现。但是,你如何处理主人失败?那么其中一名奴隶将被选为主人,所以你必须知道在哪里连接?

问这一切,因为我们使用的是RabbitMQ的集群HAProxy的前面,所以我们可以从脱钩我们的应用程序的集群结构。这样,无论何时节点完成,HAProxy都会重定向到活节点。但是当我们杀死一个兔子节点时,我们遇到了问题。与兔子的连接是永久的,所以如果失败了,你必须重新创建它。此外,你必须在这种情况下重新发送消息,否则你将失去它们。

即使所有这些,仍然可能会丢失消息,因为当我杀死一个节点时(在某些缓冲区中,网络中的某处),它们可能正在传输中。因此,您必须使用交易或发行商确认,以确保在所有镜像填满消息后交付。但这里还有一个问题。您可能有重复的消息,因为代理可能发送了从未到达生产者的确认(由于网络故障等)。因此消费者应用程序需要执行重复数据删除或以幂等方式处理传入的消息。

是否有避免这种方式?或者我必须决定是否可以丢失几条消息而不是重复某些消息?

回答

14

有人能解释一下在一个RabbitMQ集群中有多个节点和队列以镜像的方式发布到一个从节点时幕后发生了什么?

This博客概述了究竟发生了什么。

但是当我发布到从属节点会发生什么?此节点是否会将首先发送消息的信息发送给主服务器?

该消息将被重定向到主队列 - 也就是创建队列的节点。

但是,您如何处理主故障?那么其中一名奴隶将被选为主人,所以你必须知道在哪里连接?

同样,这覆盖了here。实质上,您需要一个单独的服务来轮询RabbitMQ并确定节点是否存在。 RabbitMQ为此提供了一个management API。您的发布和使用应用程序需要直接引用此服务,或者通过相互数据存储来引用此服务,以确定要发布或使用的正确节点。

与兔子的连接是永久的,所以如果它失败了,你必须重新创建它。此外,你必须在这种情况下重新发送消息,否则你将失去它们。

您需要订阅连接中断事件才能对已断开的连接作出反应。您需要在客户端建立一定程度的冗余,以确保消息不会丢失。如上所述,我建议您引入专门用于审问RabbitMQ的服务。客户端可以尝试将消息发布到最后一次已知的活动连接,如果发生故障,客户端可能会向监控服务器询问RabbitMQ群集的最新列表。假设至少有一个活动节点,客户端然后可以建立到它的连接并成功发布消息。

即使这一切,消息仍可能丢失,因为它们可能是在运输过程中,当我杀死一个节点

有,你不能与冗余覆盖某些边缘的情况下, RabbitMQ也不是。例如,当消息落入队列时,HA策略调用后台进程将消息复制到备份节点。在此过程中,消息在被保存到备份节点之前可能会丢失。如果主动节点立即失败,消息将会丢失。对此无能为力。不幸的是,当我们降低到通过网络传输的实际字节数时,我们可以构建的安全措施数量有限。

因此,消费者应用程序需要执行重复数据删除或以幂等方式处理传入消息。

您可以通过多种方式处理此问题。例如,将message-ttl设置为相对较低的值将确保重复的邮件不会长时间保留在队列中。您还可以使用唯一引用标记每条消息,并在消费者级别检查该引用。当然,这需要存储已处理消息的缓存以比较传入的消息;其思想是如果先前处理的消息到达,其标签将被消费者缓存,并且该消息可以被忽略。

我在AMQP和基于队列的解决方案中强调的一件事是,您的基础架构提供了工具,但不是整个解决方案。您必须根据您的业务需求弥补这些差距。通常,最好的解决方案是通过反复试验得出的。我希望我的建议有用。我在这里发布了许多RabbitMQ设计解决方案的博客,其中包括您提到的问题,如果您有兴趣,请致电here

+1

谢谢保罗。你是上帝。只是为了确保在执行之前能够确认这一点:1)我仍然可以使用HAProxy并且发布者确认,并且我不会丢失任何消息。我将有重复的消息,我必须以某种方式删除。我会遇到性能问题(由于第一次到达从机时会额外跳跃到主机),但我的数据将是“防弹”的。 2)为了提高性能,我将创建一个监视器服务,以便每次只将我的请求发送给主服务器,但我仍然需要处理重复的问题。谢谢。 – 2014-11-26 10:45:57

+1

您仍然可以使用HAProxy,但您会因循环配置而产生额外的网络跳数。如果你想实现负载均衡,请阅读下面的内容:http://insidethecpu.com/2014/11/17/load-balancing-a-rabbitmq-cluster/你将不会有重复的消息。我认为设置message-ttl属性足以删除重复项,尽管如前所述添加参考标记可以解决问题。我将在C#中发布一个RabbitMQ库,可以很快实现上述所有功能。继续监控我的博客的更新。 – 2014-11-26 11:06:19

+1

其实我最终有重复的消息。我跑了一次测试几次发布10000个消息到2节点兔子集群。我杀了一个节点,我收到了10011-10012条消息。我的一个消费API是幂等的,所以最终的结果是好的。非常感谢。 – 2014-11-26 11:50:09