One of the main reasons people use RabbitMQ is reliability. In many systems, losing a message is not acceptable. Imagine if an order is placed in an e-commerce system but disappears before the payment service sees it, that would be a big problem.
RabbitMQ offers three important features to ensure reliable messaging: Acknowledgments, Durability, and Persistence. Let’s understand each of them.
1. Acknowledgments (ACKs)
What it is
Acknowledgment means the consumer tells RabbitMQ that it has received and processed a message successfully.
- If the consumer sends back an ACK → RabbitMQ can safely delete the message from the queue.
- If the consumer does not send ACK (because it crashed or disconnected) → RabbitMQ will re-send the message to another consumer.
Example
Goal: Consumer uses manual ACK. On success → Ack
; on failure → Nack(requeue=true)
so the message is re-delivered.
Consumer:
// ACK EXAMPLE: manual ack + retry on error conn := mustConn(); defer conn.Close() ch, err := conn.Channel() if err != nil { log.Fatal(err) } defer ch.Close() // declare a queue (durability optional here; focus: ACK) _, err = ch.QueueDeclare("orders_queue_ack", true, false, false, false, nil) if err != nil { log.Fatal(err) } // fair dispatch: 1 message at a time if err := ch.Qos(1, 0, false); err != nil { log.Fatal(err) } msgs, err := ch.Consume("orders_queue_ack", "", false, false, false, false, nil) if err != nil { log.Fatal(err) } for d := range msgs { log.Printf("process: %s", d.Body) // simulate work if string(d.Body) == "fail" { // negative ack -> requeue for retry _ = d.Nack(false, true) // multiple=false, requeue=true continue } time.Sleep(500 * time.Millisecond) _ = d.Ack(false) // confirm processed }
Options
- Auto ACK: RabbitMQ deletes the message immediately after delivery (less safe).
- Manual ACK: The consumer decides when to send ACK (recommended for reliability).
Category: RabbitMQ