我遇到了处理与特定源相关的事件的情况。每个源都有一个密钥或ID,我可以用它作为散列。来自每个来源的事件必须按顺序处理,但是来自不同来源的事件可以并行化,以实现水平可伸缩性。将有数百个源密钥。使用一致的哈希交换绑定的过期队列上的死信刻录消息
我打算在将消息提交给RabbitMQ时将密钥设置为路由密钥的一部分,然后使用consistent-hash-exchange
,以便将来自同一源的事件路由到同一队列。当时我正在考虑使用TTL动态绑定来自消费者的私有队列(以便在消费者关闭的情况下优雅地删除它们)。一开始我只有2或3个消费者用于冗余,但是如果我想通过增加消息数量来扩大规模,我可以启动另一个消费者。
我的问题是如果消费者关闭并且队列中有消息会发生什么?理想情况下,我希望将队列中的消息重新路由回交换机,由consistent-hash-exchange
将它们路由到不同的队列(因为原始队列将不再存在)。
关于dead lettering的RabbitMQ文档没有明确提及消费者队列上的TTL场景,或者是在队列被删除时会发生什么情况。
我的方法有道理吗?如何在保留特定路由密钥的排序的同时实现消费者的容错功能?
注:我知道甚至有一个更微妙的竞争条件,如果在路由死信字母邮件的过程中到达交换新邮件到达最初路由到过期队列,现在将被路由到不同的消费者,因此在该特定情况下订单将被打破。
感谢您的回复。关于频率,在高峰时间消息数量相当多。我可能会过度设计这一点。如果消费者消失,我所寻找的是一种自动重新路由消息。我想我可以让消息TTL比队列TTL更短,这样如果消费者断开连接,消息先是DLXed,然后队列TTL过期并被删除。是的,仍然存在订购DLX消息和竞争条件与来自相同源密钥的新消息的问题。 – jbx
不客气。正如我所说,我会为消费者解决这个“消费方面的问题”。你想要消费者为了继续处理顺序,但也希望它运行:) – cantSleepNow
是的,我的担心是更多的如果运行消费者的机器死亡,需要超过几分钟才能恢复。公平地说,如果队列具有相对较短的TTL(例如30秒)并且消费者不重新连接,那么将会有潜在的30秒的新消息。我对DLXing的假设不起作用,因为消息可能在队列TTL到期之前的最后一秒进入。或者,我可以在客户端断开连接后立即删除队列,以便只丢失几条消息...不理想丢失消息:( – jbx