RabbitMQ Basic恢复不起作用

时间:2011-06-14 08:25:48

标签: c# rabbitmq

我们有一个持久的RabbitMQ队列。当消费者从队列中获取项目时,它会对其进行处理,然后对其进行确认。如果消费者未能处理该项目,则会打印错误,期望有人解决问题并停止。没有发送确认。当消费者重新启动它时,它接收的项目是队列中的下一个项目,而不是没有ack的项目。 Basic.Recover()没有帮助(使用.NET客户端)。 任何想法如何让它作为一个队列工作 - 总是得到第一个项目,如果它没有被激活。

3 个答案:

答案 0 :(得分:3)

可以通过两种方式使用消息noAck = false或noAck = true

noAck是Model.BasicConsume和Model.BasicGet上的参数

当noAck设置为true时,邮件会在传递后自动从队列中删除。如果noAsk设置为false,则只有在调用basicAck时才会删除消息。

如果noAck = false并且您没有调用basicAck,则消息将保留,但在您重新启动应用程序(或关闭首先使用它的连接)之前,您将不会接收其他消费者。如果您致电BasicReject,该消息将被重新发送给订阅者。

我希望这会有所帮助。

答案 1 :(得分:3)

this entry in the RabbitMQ FAQ。虽然您可能希望RabbitMQ将未经处理的消息重新排队到队列的头部(消费者将其拉下来之前),但实际情况可能会有所不同,正如您所经历的那样。

所以Basic.Recover()不起作用(消息 重新放回队列以供将来重新处理),只是因为它不能按预期方式工作。

我脑子里的一些东西告诉我,你可能能够通过设置预取计数为1并且最多只有一个消费者连接到任何队列来获得你想要的行为时间,但我无法保证是这样的。值得一试。然而,即使它工作也不依赖于永远保持这种情况,并且如此低的预取计数,消费者的消息/第二次性能可能会受到影响。

答案 2 :(得分:0)

您可以通过拥有一对队列,一个高优先级和一个普通优先级来获得此行为。将预取计数设置为1,然后使用basic.get在队列之间切换。大多数情况下,优先级队列为空,但是当您想要重新排队时,请将该消息再次发布到高优先级队列上。

这适用于您有多个进程正在使用消息流的情况,并且一个进程决定对消息进行挽救。该消息几乎会立即被另一个进程接收。