Acknowledgements: auto-ack is a data-loss switch
Manual ack is what makes at-least-once delivery real, and it changes the states a message can be in.
Open this lesson in the learning hubKey points
- Auto-ack acks at delivery time, so a consumer crash mid-work loses the message for good.
- Manual ack means
basic.ackafter the work succeeded, not when the handler starts. basic.nackis a RabbitMQ extension: unlike basic.reject it can reject many delivery tags at once.- Unacked messages are tracked per channel, so closing that channel requeues every one of them.
- RabbitMQ 3.8.15 added
consumer_timeout; the default is 30 minutes and it closes the channel. - Delivery tags are per channel and increase monotonically - never ack a tag on another channel.
Example
boolean autoAck = false; // the important argument
ch.basicQos(20); // never consume without this
ch.basicConsume("invoicing", autoAck, (tag, delivery) -> {
long deliveryTag = delivery.getEnvelope().getDeliveryTag();
try {
invoiceService.handle(delivery.getBody());
ch.basicAck(deliveryTag, false); // false = just this one
} catch (TransientException e) {
ch.basicNack(deliveryTag, false, true); // requeue: try again
} catch (PermanentException e) {
ch.basicNack(deliveryTag, false, false); // to the DLX, not back
}
}, tag -> { });
Ack after the work, nack with requeue false plus a DLX for anything that will never succeed.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the RabbitMQ Course course, and every lesson in it is listed on the RabbitMQ Course contents page.