作为一般规则,您可以考虑如果您的消费者正常运行,您应该始终发出消息,无论处理消息的结果如何(错误或成功)。
您可以使用requeue = false拒绝/删除格式错误的消息,将其路由到死信交换并对其执行操作(绑定队列并使用例如事后分析),或选择确认并执行任何必要的操作(例如发送BadRequest消息等其他消息,...)。
(几乎)永远不会有问题的最好方法是作为处理消息的最后一个动作,并准备好处理重新发送(幂等可能会有所帮助)。您可以在交付时立即确认,但如果消费者崩溃,则消息丢失(您需要自己处理该案例 C有很多模式)。
希望这可以帮助。
Nack 是针对AMQP协议的RabbitMQ特定增强功能。它允许消息的使用者在消息时通知服务器 的 不是 强> 成功处理。我假设你已经走到这一步了。
Nack
这里有趣的是AMQP最初没有考虑过 Nack 有必要。为什么?因为消费者无法处理消息时的AMQP行为是针对消费者的 没有关闭连接 ack - 消息 。在这种情况下,邮件会按照原来的顺序自动重新排队,并通过邮件传递给下一个可用的使用者 redelivered 国旗套。
ack
redelivered
为什么会这样?
因为一个 Nack 表示消费者的问题,而不是消息。如果消息本身不好,AMQP认为消费者会足够聪明地认识到这一点, ack 消息,然后采取程序员设计的任何其他步骤来处理坏消息。
RabbitMQ补充说 Nack 需要的功能 requeue 参数。默认情况下, requeue 是真的 - 这意味着经纪人将重新排列信息。这符合AMQP设计的初衷。但是,如果你通过 requeue 如果不对,那么经纪人就会把这封邮件写死信。这是通常由智能应用程序架构师使用AMQP设计的行为的快捷方式,因此您可以将其视为程序员的便利。
requeue
的 两者之间的差异 强>
在第一种情况下, Nack 指出消息使用者的问题。消费者应该在解决问题时脱机。在第二种情况下, Nack 表示邮件有问题。第一种情况是暂时性问题,而第二种情况是永久性失败。
的 如果我无法处理特定消息该怎么办? 马上 但也许以后呢? 强>
如果您的消息传递结构设计得当,那将永远不会成真。如果一个特定消息需要与另一个消息不同的处理路径或资源,则该消息类型应具有其自己的队列。当处理这些消息的依赖项脱机或不可用时,该队列的消费者可以停止使用。
问题:我的经验:在发布/订阅场景中,如果订阅者无法收到消息,则nacked消息会立即在队列前面重新排队,并且它将成为订阅者获取的下一条消息。
对,那是正确的。邮件重新排队时 channel.basicNack,它将被置于其原始位置 队列,如果可能的话。如果不是(由于同时交付和 当多个消费者共享时,来自其他消费者的确认 队列),消息将被重新排队到更接近队列的位置 头。资源: https://www.rabbitmq.com/nack.html
问题:有没有办法避免这种情况?是否有可能以一种下一条消息绝对不是那个刚刚被劫持的方式来消息?
用nack来实现这一目标是不可能的。实现此目的的一种方法是将消息重新发布回需要nack的队列。