Implementing RabbitMQ Dead Letter Queues with Go
This article explains the concept of RabbitMQ dead letter queues, outlines the conditions that generate dead letters, provides step‑by‑step configuration instructions, and includes Go code examples for publishing messages with TTL and consuming from the dead‑letter queue to implement delayed processing.
In many systems, task execution timeouts cause task status to remain unchanged, leading to poor user experience; a solution is to use RabbitMQ's dead letter queue (DLQ) mechanism.
A dead letter in RabbitMQ occurs when a message is negatively acknowledged with channel.basicNack or channel.basicReject without requeue, when the message exceeds its TTL, or when the queue length exceeds its maximum; such messages are then routed to a configured dead‑letter exchange.
To configure a DLQ, first create a dead‑letter exchange (e.g., exchange.dlx ) and bind two queues: queue.normal and queue.dlx . Then set the x-dead-letter-exchange argument on queue.normal to point to exchange.dlx and optionally configure a TTL for messages in queue.normal . Finally, publish messages to queue.normal ; when they expire they will be routed to queue.dlx for consumption.
Example Go code for publishing messages with a 5‑second TTL and specifying the dead‑letter exchange:
package main
import (
"fmt"
"github.com/streadway/amqp"
"time"
)
func main() {
conn, _ := amqp.Dial("amqp://user:password@host:ip/vhost")
ch, _ := conn.Channel()
body := "Hello World " + time.Now().Format("2021-10-20 15:04:05")
fmt.Println(body)
//声明交换器
args := amqp.Table{"x-dead-letter-exchange": "exchange.dlx"}
// 声明一个queue.normal队列,并设置队列的死信交换机为"exchange.dlx"
q, _ := ch.QueueDeclare("queue.normal", true, false, false, false, args)
ch.Publish("", q.Name, false, false, amqp.Publishing{
Body: []byte(body),
Expiration: "5000", // 设置TTL为5秒
})
// defer 关键字
defer conn.Close() // 压栈 后进先出
defer ch.Close() // 压栈 后进先出
}Example Go code for consuming messages from the dead‑letter queue:
package main
import (
"fmt"
"github.com/streadway/amqp"
)
func main() {
conn, _ := amqp.Dial("amqp://xxx:xxx@host:ip/vhost")
ch, _ := conn.Channel()
//监听queue.dlx队列
msgs, _ := ch.Consume("queue.dlx", "", true, false, false, false, nil)
for d := range msgs {
fmt.Printf("receive: %s\n", d.Body) // 收到消息,业务处理
}
}In summary, using TTL combined with a dead‑letter queue provides an effective delayed‑queue solution for scenarios such as order timeout cancellation and retry mechanisms, and the provided Go examples demonstrate a practical implementation.
360 Quality & Efficiency
360 Quality & Efficiency focuses on seamlessly integrating quality and efficiency in R&D, sharing 360’s internal best practices with industry peers to foster collaboration among Chinese enterprises and drive greater efficiency value.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.