RabbitMQ(和node.js)中的异步确认

时间:2011-09-13 10:03:05

标签: javascript node.js rabbitmq amqp

我有一个针对RabbitMQ的特定用例,我想澄清某些事情并寻求建议。

考虑这种情况:

1-我发布了两条消息,即要执行的任务:messageA,然后是messageB

2-我的消费者获取messageA,执行此消息中包含的任务,但在任务运行时,服务器崩溃

我的问题是:当服务器重新启动时,messageA是否会被重新排队,并且会在messageB之前重新排队(与崩溃前的顺序相同)?

根据我的理解,如果服务器崩溃,messageA将会丢失,因为我的消费者在接收到消息后默认已经确认了它。

所以我的想法是分别使用和确认消息:首先消耗,运行任务,然后在任务成功执行时确认消息。

你觉得这种方法有问题吗?你能建议我做别的吗?

2 个答案:

答案 0 :(得分:1)

RabbitMQ不会保留重新排队的消息顺序:

  

在大多数情况下,是的。假设发布者发布消息M1,M2,M3   和M4(按此顺序)在同一个通道上并具有相同的路由   信息。如果这些消息被路由到队列,那么他们将   最终按照他们发布的顺序排列。消费在   队列将产生M1,M2,M3,然后产生M4。

     

但是,只有在没有重新排队的情况下才会保证订单。一个   如果消费者关闭频道,则消息将被隐式重新排队   在收到消息之前例如,如果消费者收到M1,   没有确认和关闭频道然后下一个消费者将   按M2,M3,M4,M1的顺序接收消息。消息也可以   如果消费者调用basic.recover {requeue = true},则显式重新排队。   关于至少一次交付的常见问题解答还有更多内容   细节。

RabbitMQ FAQ

这可以完成,但RabbitMQ不会自动完成,您需要通过将子消息包装在父消息中来自行管理生命周期。然后,如果消息1成功但消息2失败,您将拥有管理父消息和处理回滚的代码。希望这有助于..

最好的问候

答案 1 :(得分:0)

在no-ack模式下消耗的消息(请参阅http://www.rabbitmq.com/amqp-0-9-1-reference.html#domain.no-ack)在服务器崩溃后不会被重新排队,因为服务器在交付时完全忘记了这些消息。消费者在交付后对此类消息负责。

仅在成功完成任务后确认消息才是您方案中的正确方法。如果您希望消息在代理崩溃后继续存在,那么您还必须确保该队列是持久的并且消息是持久发布的(交付模式2),并且发布者确认或事务用于确保将消息写入磁盘

如果代理在处理messageA时崩溃,则将保留消息顺序。如果消费者而不是经纪人崩溃,那么消息顺序将被颠倒。