RabbitMQ中的Ack或Nack意味着什么?

44
我正在使用RabbitMQ,通过basic_get从队列中获取每个消息,但不会自动确认过程,这意味着消息将保留在队列中,直到我确认或拒绝该消息。
有时候,由于某些异常抛出导致无法完全处理消息,因此会出现无法处理的消息。
问题是,在成功和异常情况下是否都确认消息,对于结果消息都将离开队列,那么在这种情况下使用ack或nack有何影响?也许我对每个操作的使用有所遗漏?

2
唯一的区别是 nack 允许重新排队,而 ack 不允许吗? - JavaSa
2个回答

101

basic.nack 命令是 RabbitMQ 的扩展功能,它扩展了 basic.reject 的功能,包括批量处理模式。两者都包含一个名为“requeue”的布尔标志,因此您实际上有几个选择:

  • nack/reject 使用 requeue=1:消息将被返回到原始队列,就像它是一条新消息一样;这可能在消费者端临时失败的情况下非常有用。
  • nack/reject 使用 requeue=0 和配置了死信交换机(DLX):将该消息发布到该交换机,以便其可以被另一个队列接收。
  • nack/reject 使用 requeue=0 且没有 DLX 将会直接丢弃该消息。
  • ack 将从队列中删除该消息,即使配置了 DLX 也是如此。

如果您没有配置 DLX,则始终使用 ack 将与使用 nack/reject 使用 requeue=0 是相同的;然而,从一开始使用正确的函数将为您提供更多配置灵活性。


1
非常棒的回答!不过您能否澄清一下DLX是否已被视为队列,以及队列和交换机之间的区别是什么? - JavaSa
1
@JavaSa 一个常见的比喻(可能对你有意义,也可能没有)是交换机就像邮局,队列就像邮箱。你只会向交换机发布新消息(即使它是默认交换机);然后交换机将根据其“路由键”将其路由到零个、一个或多个队列中。因此,最简单的死信交换机将把所有内容路由到单个队列中,但它也可以像你需要的那样复杂。 - IMSoP
1
“nack”代表否定的确认。 - cs_pupil

6

Ack和Nack都会从队列中删除消息,区别在于当您Nack一条消息时,如果为该队列定义了DLX(死信队列),则该消息将进入DLX。


2
如果您使用Nack并将requeue选项设置为true,则不会这样做。将其设置为true将从消费者的获取中删除消息,并将其添加回原始队列以进行重新处理。 - code5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接