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



我脑海中有一个RabbitMQ的特定用例,我想澄清一些事情并征求建议。

考虑这个场景:

1-我发布两条消息,它们是要执行的任务:messageA和messageB

2-我的消费者获得messageA,执行该消息中包含的任务,但是当任务正在运行时,服务器崩溃

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

据我所知,如果服务器崩溃,messageA将丢失,因为我的消费者在接收消息时默认已经确认了它。

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

你认为这种方法有问题吗?你还建议我做些什么吗?

RabbitMQ不保持队列消息的顺序:

在大多数情况下,是的。假设发布者发布消息M1, M2, M3和M4(按此顺序)在同一通道上使用相同的路由信息。如果这些消息被路由到一个队列,那么它们将被发送以它们发布的顺序结束。消费队列将产生M1、M2、M3和M4。

但是,只有在没有排队的情况下才能保证顺序。一个如果消费者关闭通道,将隐式地请求消息在回复消息之前。例如,如果消费者收到M1,如果返回失败并关闭通道,则下一个消费者将关闭通道按照M2、M3、M4、M1的顺序接收消息。消息也可以是如果消费者调用basic.recover{requeue=true},则显式请求。关于至少一次交付的常见问题讨论了更多细节。

RabbitMQ常见问题

这是可以做到的,但RabbitMQ不会自动完成,你需要自己管理生命周期,将子消息包装在父消息中。然后,您将拥有管理父消息的代码,并在消息1成功但消息2失败时处理回滚。希望这对你有帮助。

在服务器崩溃后,以no-ack模式使用的消息(参见http://www.rabbitmq.com/amqp-0-9-1-reference.html#domain.no-ack)将不会被排队,因为服务器在传递这些消息时已经完全忘记了它们。消费者在交付后对这些消息负责。

在您的场景中,只有在成功完成任务后才确认消息是正确的方法。如果您希望消息在代理崩溃时仍然存在,那么您还必须确保队列是持久的,并且消息是持久发布的(交付模式2),并且使用发布者确认或事务来确保消息被写入磁盘。

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

最新更新