我遇到的情况是我正在处理与特定来源相关的事件。每个源都有一个密钥或ID,我可以将其用作哈希。必须按顺序处理来自每个源的事件,但可以并行化来自不同源的事件,以实现水平可伸缩性。将有数百个源键。
我计划在向RabbitMQ提交消息时将密钥设置为路由密钥的一部分,然后使用consistent-hash-exchange
以便将来自同一源的事件路由到同一队列。然后我考虑使用TTL动态绑定来自消费者的私有队列(以便在消费者关闭时优雅地删除它们)。在开始时我将只有2或3个消费者用于冗余,但如果我想通过增加消息数量来扩展,我可以启动另一个消费者。
我的问题是如果消费者关闭并且队列中有消息会发生什么?理想情况下,我希望将队列中的消息重新路由回交换机,consistent-hash-exchange
将它们路由到不同的队列(因为原始队列将不再存在)。
关于dead lettering的RabbitMQ文档没有明确提到消费者队列上的TTL场景,或队列被删除时会发生什么。
我的方法有意义吗?如何在保留特定路由密钥的排序的同时实现我正在寻找的消费者容错?
注意:我知道如果在将死信的消息路由到交换机的过程中,最初路由到过期队列的过程中会出现更微妙的竞争条件,现在这些消息将被路由到不同的消费者,因此订购将在该特定实例中被打破。
答案 0 :(得分: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,check this link - 它基本上是队列的“到期时间”。此外,如果队列被删除,则消息消失(当然没有考虑任何镜像)。
现在对于“它是否有意义”的一部分。对于来自不同来源的消息,我认为很清楚 - 尽可能多地并行处理,就是这样。那里没有碰撞(通常没有)。
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等),如果你真的想要保持序列的原始顺序(故意冗余地说: ))