0

我有一种情况,我正在处理与特定来源相关的事件。每个源都有一个键或 ID,我可以将其用作散列。来自每个源的事件必须按顺序处理,但来自不同源的事件可以并行化,以实现水平可伸缩性。将有数百个源密钥。

我计划在向 RabbitMQ 提交消息时将密钥设置为路由密钥的一部分,然后使用consistent-hash-exchange以便将来自同一源的事件路由到同一队列。然后我正在考虑使用 TTL 动态绑定来自消费者的私有队列(以便在消费者关闭时优雅地删除它们)。一开始我只会有 2 或 3 个消费者来实现冗余,但如果我想因消息数量增加而扩大规模,我可以启动另一个消费者。

我的问题是如果消费者宕机并且队列中有消息会发生什么?理想情况下,我希望将队列中的消息重新路由回交换器,并将consistent-hash-exchange它们路由到不同的队列(因为原始队列将不再存在)。

RabbitMQ 关于死信的文档没有明确提到消费者队列上的 TTL 场景,或者当队列被删除时会发生什么。

我的方法有意义吗?如何在通过特定路由键保留排序的同时实现我正在寻找的消费者容错?

注意:我知道如果在将死信消息路由到交换器的过程中,会出现更微妙的竞争条件,新消息最初路由到过期队列,现在将路由到不同的消费者,因此排序将是在那个特定的情况下被打破。

4

1 回答 1

0

这里有不止一个问题要回答,我会尝试按相同的顺序进行。

My question is what happens if a consumer is down and there are messages in its queue?
在上下文之外(问题的其余部分) - 消息保留在队列中,直到它们被确认或它们的 TTL 过期。

The RabbitMQ documentation about dead lettering doesn't explicitly mention the scenario of TTL on consumer queues, or what happens when the queue gets deleted.
确实...The TTL for the message expires...,所以基本上如果消息在给定的 TTL 内没有被确认,它就会到达 DLX。对于队列 TTL,请检查此链接- 它基本上是队列的“到期时间”。此外,如果队列被删除,消息就会消失(当然不考虑任何镜像)。

现在对于“它是否有意义”部分。对于来自不同来源的消息,我认为很清楚 - 尽可能多地并行处理,仅此而已。那里没有碰撞(通常没有)。

How can I achieve the consumer fault-tolerance I am looking for while retaining the ordering by a specific routing key?
对于顺序处理,基本上你需要一个消费者来做一个来源。现在为了监控这个消费者,可能会添加一个看门狗来在它崩溃时重新启动它,或者在挂起时重新启动它等等。也许使用get而不是consume(amqp) 方法也是有意义的。我不能真正推荐或不推荐这种方法,因为(至少对我而言)它是特定于用例的(性能、新消息的频率等),但我会说这样更容易实现“更同步”的行为。

当然(现在指的是你在笔记中写的内容)如果你真的想保持序列的原始顺序(故意重复地说),你应该尽量避免 DLX-ing 消息(更高的 TTL 等)

于 2016-10-03T13:12:16.887 回答