Cheat SheetsRabbitMQReliability

Reliability — Cheat Sheet

RabbitMQ · 3 topics. Download the PDF or the Instagram carousel and share it.

Cheat Sheet · AiCanCode.org
Reliability
RabbitMQ3 topicsQuick revision reference
1

Publisher Confirms

Publisher confirms are an async acknowledgement from the broker that a message was routed and written; essential to know a message is not lost between producer and broker.

  • Without publisher confirms, basicPublish is fire-and-forget — messages can be silently lost on broker failure or network drop.
  • Confirm mode (channel.confirmSelect) assigns a delivery tag to each message; broker sends ack or nack asynchronously.
  • Async confirm listeners (addConfirmListener) are preferred over waitForConfirms() for production throughput.
  • Spring AMQP: set publisher-confirm-type=CORRELATED and ConfirmCallback + ReturnsCallback on RabbitTemplate.
  • Publisher confirms + durable queues + persistent messages = complete end-to-end message durability guarantee.
  • Channel transactions are ~250× slower than confirms — use confirms for throughput-sensitive production code.
Java — Publisher Confirms (AMQP Client)
Channel channel = connection.createChannel();

// Put channel in confirm mode — every publish gets a sequence number
channel.confirmSelect();

// Async confirm listener — fires on broker ack or nack
channel.addConfirmListener(
    (deliveryTag, multiple) -> {
        // ACK: broker persisted the message
        log.info("Confirmed delivery tag {}", deliveryTag);
    },
    (deliveryTag, multiple) -> {
        // NACK: broker could NOT persist — resend or alert
        log.error("Broker nacked delivery tag {} — message lost!", deliveryTag);
        retryPublish(deliveryTag);
    }
);

// Publish a persistent message
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
    .deliveryMode(2)   // persistent
    .build();

channel.basicPublish("orders", "order.created", props, messageBody);

// Synchronous wait — blocks until all pending confirms arrive (lower throughput)
boolean allConfirmed = channel.waitForConfirms(5000); // 5s timeout
if (!allConfirmed) {
    throw new RuntimeException("Some messages not confirmed by broker");
}
2

Consumer Acknowledgements (ack/nack)

basicAck signals successful processing; basicNack/basicReject requeues or discards the message. Unacknowledged messages are redelivered if the consumer disconnects.

  • Manual-ack (autoAck=false) is the safe default: messages are requeued if the consumer crashes before acking.
  • basicAck → processed successfully; basicNack(requeue=true) → retry; basicNack(requeue=false) → dead-letter or discard.
  • Never requeue=true for a message that always fails — it creates an infinite poison-message loop; route to DLQ instead.
  • Set prefetch (basicQos) together with manual ack for fair dispatch: each consumer only receives the next message after acking the previous one.
  • Auto-ack deletes the message on delivery — before processing — acceptable only for non-critical fire-and-forget scenarios.
  • In Spring AMQP, set acknowledge-mode: MANUAL and inject Channel into the @RabbitListener method to call ack/nack.
Java — AMQP Manual Ack
Channel channel = connection.createChannel();

// Set prefetch — limits unacked messages to 1 (fair dispatch)
channel.basicQos(1);

// Consume with manual ack (autoAck = false)
channel.basicConsume("order-queue", false, (consumerTag, delivery) -> {
    long deliveryTag = delivery.getEnvelope().getDeliveryTag();
    try {
        Order order = deserialize(delivery.getBody());
        orderService.process(order);

        // SUCCESS — ack the message; broker removes it
        channel.basicAck(deliveryTag, false);

    } catch (TransientException e) {
        // Transient failure — requeue for retry
        channel.basicNack(deliveryTag, false, true);

    } catch (PoisonMessageException e) {
        // Permanent failure — do NOT requeue; routes to DLX if configured
        channel.basicNack(deliveryTag, false, false);
    }
}, consumerTag -> {});
3

Prefetch Count & QoS

basicQos limits the number of unacknowledged messages a consumer can hold; low prefetch ensures even work distribution and prevents a slow consumer from monopolising the queue.

  • basicQos(n) stops the broker delivering more than n unacked messages to a consumer
  • prefetch=1 gives the fairest distribution; higher values improve throughput
  • Spring AMQP default prefetch is 250 — lower it for slow/CPU-heavy tasks
  • global=false (default) applies the limit per consumer; global=true per channel
  • Always combine manual ack with a sensible prefetch — auto-ack ignores QoS
  • Monitor unacked message counts in Prometheus to find the optimal value
Java — AMQP client basicQos
// AMQP Java client
Channel channel = connection.createChannel();
// Allow at most 5 unacknowledged messages per consumer
channel.basicQos(5 /*, global= false (default) */);

channel.basicConsume("orders", false, (tag, delivery) -> {
    try {
        process(delivery.getBody());
        channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
    } catch (Exception e) {
        // requeue=false → routed to DLX if configured
        channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, false);
    }
}, tag -> {});
Learn this free with Aria, your AI tutor → AiCanCode.org/learn/rabbitmq