benbrougher.tech

Consuming RabbitMQ Messages in Go

November 20, 2023

When building distributed systems and microservices, RabbitMQ is commonly used for message queuing and asynchronous communication. The RabbitMQ Go module makes it easy to publish and consume messages, but working with message acknowledgements and retries can be difficult. In this post, we’ll cover how to properly consume, acknowledge, and retry RabbitMQ messages using the Go client.

Consuming Messages

The Channel.Consume method is used to consume messages from a RabbitMQ queue as a Go channel:

msgs, err := ch.Consume(
    "my-queue",
    "",
    false,
    false,
    false,
    false,
    nil,
)

for d := range msgs {
   // message processing
}

The Consume channel blocks until new messages arrive. So ranging over it with a for loop will process each message sequentially.

Acknowledging Messages

To prevent message loss, RabbitMQ requires acknowledging messages once processed successfully:

err := msg.Ack(false)

This removes the message from the queue only after it is acknowledged. The false parameter prevents additionally delivered messages.

Retrying Failed Messages

To retry a failed message, you can reject it and it will be re-queued:

err := ch.Reject(msg.DeliveryTag, true)

The requeue parameter set to true puts it back on the queue.

Alternatively, you can publish the failed message to a dead letter exchange and queue to retain it but put aside for later handling. This gives developers the option to replay events once they have fixed a problem, minimizing data loss for the user and increasing system resilience.

Consuming Concurrently

While ranging over messages occurs sequentially, to process concurrently we can start a worker pool:

for i := 0; i < 10; i++ {
    go func() {
        for d := range msgs {
             // handle message
        }
    }()
}

This fires up 10 goroutines to process messages in parallel from the RabbitMQ channel. This means that this application can be processing up to 10 messages concurrently at a time, all without blocking the messages coming in.

Conclusion

And there you have it - an overview of consuming, acknowledging, and retrying failed messages with the RabbitMQ Go client! Proper acknowledgement handling prevents losing messages while retries and dead lettering enables robust processing.

Buy Me A Coffee

Written by Ben Brougher who lives and works in the Pacific Northwest developing solutions to problems (usually with software). He graduated 2020 from Eastern Washington University as a Computer Science Major, Bachelor of Science (BS), and works engineering and developing software solutions in the enterprise telecommunications industry.

Bluesky
← Back to Blog Posts

@moutansos@mastodon.social