具有重新排队的BasicReject实际上去了哪里?

时间:2016-06-08 18:11:40

标签: rabbitmq

这似乎是一个简单的问题,但我很难找到明确的答案。如果在RabbitMQ 3.6.1中我有一个如下所示的队列:

5  4  3  2  1  <= head

我消耗消息1,然后执行:

channel.BasicReject(ea.DeliveryTag, true);

1最终会在队列的末尾还是在队列的末尾(假设为了简单起见,当时没有其他人在消耗队列)?我最终会得到:

1  5  4  3  2  <= head

或:

5  4  3  2  1  <= head

无论如何要控制它(一种方法是回复消息并完全重新发布它我想)?我实际上想要第一种情况,因为我拒绝1,因为处理该消息所需的特定资源当前不可用。所以我想把它扔回队列以便稍后处理(当资源可用时)或者被其他人(有资源可用)接收。但我不想再把它扔回去继续捡起它。

3 个答案:

答案 0 :(得分:4)

我说答案是here,我引用了一部分:

  

可以使用具有该功能的AMQP方法将消息返回到队列   一个重新排队参数(basic.recover,basic.reject和basic.nack),或   由于频道关闭而持有未确认的消息。任何   这些场景导致消息在后面重新排队   RabbitMQ的队列早于2.7.0发布。来自RabbitMQ发布   2.7.0,即使存在重新排队或频道关闭,消息也始终以发布顺序保留在队列中。

因此我们可以假设RMQ以这种方式实现,消息不会从队列中删除(物理删除),直到它们被确认,它们可能有一个ACKed标志或其他。

答案 1 :(得分:0)

就是这样,因为如果它是FIFO。 (先进先出)。当你重新排队时,它现在是&#34;最后在&#34;。

1  5  4  3  2  <= head

请参阅下面的文章,讨论&#34;重试最多重试次数&#34;

https://dotnetcodr.com/2014/06/19/rabbitmq-in-net-c-more-complex-error-handling-in-the-receiver/

答案 2 :(得分:0)

为像我这样迟到并需要非“阅读文档”答案的人明确回答:

将消息重新排队时,如果可能,它将被放置到其队列中的原始位置。否则(由于多个消费者共享一个队列时,由于其他消费者的并发传递和确认),该消息将重新排队到更靠近队列头的位置。 -从Rabbitmq的官方网站-rabbitmq.com/nack.html – smc

使用您的示例在(当前)最高答案中扩展此评论

我有一个看起来像这样的队列:

false

我消耗了消息1

队列现在为:5 4 3 2 1 <= head

然后做:5 4 3 2 <= head

您的结果将与初始结果相同

channel.BasicReject(ea.DeliveryTag, true);

如果您只有一位消费者。如果有多个消费者,则可能会发生以下情况:

初始:5 4 3 2 1 <= head

消费者1接受以下消息:5 4 3 2 1 <= head

消费者2正在处理消费者1时,消费者2接受消息:5 4 3 2 <= head

消费者1决定拒绝并重新排队,结果是:5 4 3 <= head