I assume that you know what Dead Letter Exchange (DLX) is in RabbitMQ. If you don't then you should read the documentation. In short, if your message is not consumed for some reason, it gets put into another queue for investigation so on. Make sure that the dead letter exchange and the queue is declared before others otherwise messages will be silently dropped.


Setup


I assume that you already have a consumer application working fine. Let's add a dead letter exchange and queue to it.


# The current properties
ExchangeType: direct
ExchangeName: user
RoutingKey: create
QueueName: user_create

# New DLX properties
ExchangeType: fanout
ExchangeName: user_dlx
QueueName: user_create_dlx

New DLX declarations


Keep the exchange type as fanout no matter what the other is.


if err := channel.ExchangeDeclare(
"user_dlx",
"fanout",
true,
false,
false,
false,
nil,
); err != nil {
return err
}

if _, err := channel.QueueDeclare(
"user_create_dlx",
true,
false,
false,
false,
nil,
); err != nil {
return err
}

if err := channel.QueueBind(
"user_create_dlx",
"",
"user_dlx",
false,
nil,
); err != nil {
return err
}

Modifications


Just adding amqp.Table{"x-dead-letter-exchange": "user_dlx"}, to the configuration. This goes to your existing queue.


if _, err := channel.QueueDeclare(
"user_create",
true,
false,
false,
false,
amqp.Table{"x-dead-letter-exchange": "user_dlx"},
); err != nil {
return err
}

Test


If you use code below in the consumer, it will take the message out of the original queue and put into DLX queue.


message.Nack(false, false)