My experience: in a publish/subscribe scenario, if a subscriber nacks a message, the nacked message is immediately re-queued at the front of the queue and it will be the next message the subscriber gets.
Is there a way to avoid this? Is is possible to nack a message in a way that the next message will definetly not be the one just nacked?
I am using Node.js and amqp.node to communicate with RabbitMQ
Nack
is a RabbitMQ-specific enhancement to the AMQP protocol. It allows a consumer of a message to notify the server when a message was not successfully processed. I assume you got this far already.
The interesting thing here is that AMQP did not originally consider Nack
to be necessary. Why? Because the AMQP behavior when a consumer is unable to process a message is for the consumer to close the connection without ack
-ing the message. Under this situation, the message is automatically requeued in the order it was originally in, and delivered to the next available consumer with the redelivered
flag set.
Why would this be?
Because a Nack
indicates an issue with the consumer, not the message. If the message itself is bad, AMQP assumed that the consumer would be smart enough to recognize this, ack
the message, then take whatever other steps the programmer designed to deal with bad messages.
RabbitMQ added the Nack
function which takes a requeue
parameter. By default, requeue
is true - meaning upon the nack, the broker will requeue the message. This is in keeping with the original intent of the AMQP design. However, if you pass requeue
as false, the broker will dead-letter the message. This is a shortcut to the behavior that would normally have been designed in by a smart application architect using AMQP, so you can think of this as a convenience to the programmer.
Difference Between The Two
In the first case, the Nack
indcates a problem with the message consumer. The consumer should take itself offline while it works out its issues. In the second case, the Nack
indicates a problem with the message. The first case is a transient issue, while the second is a permanent failure.
What if I can't process a particular message right now but maybe later?
If your messaging structure was designed properly, this would never be true. If one particular message requires different processing paths or resources than another message, that message type should have its own queue. Consumers of that queue can stop consuming when a dependency for processing those messages is offline or unavailable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With