RabbitMQ does not natively support delayed messages. Currently, the main implementations include using a dead-letter exchange + message TTL scheme or the rabbitmq-delayed-message-exchange plugin.

Use cases for delayed queues

  • Scenarios where there are time window requirements for message production and consumption. For example, in e-commerce transactions, there is a scenario where orders are closed if payment is not completed within a timeout period. In this case, a delayed message is sent when the order is created. This message will be delivered to the consumer 30 minutes later, and the consumer needs to check if the corresponding order has been paid. If payment is not completed, the order is closed; if payment is completed, the message is ignored.
  • Scenarios where delayed tasks are triggered by messages. For example, sending reminder messages to users after a specified time period.

Dead-letter exchange + message TTL scheme

The core idea of this approach is to create a queue without consumers and utilize message expiration time (TTL). When a message expires, it becomes a dead letter, which is routed to a dead-letter exchange, and then to a dead-letter queue, which can be consumed.

In this approach, the message expiration time serves as the message delay time. For example, if the message TTL is set to 30 seconds and there are no consumers for the queue, the message will expire after 30 seconds and become a dead letter, which will be handled by the dead-letter queue.

To implement this approach, the properties need to be set as described in the following two tutorials:

Delayed message plugin solution

1. Installing the plugin

rabbitmq-delayed-message-exchange GitHub repository:

https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases

Download the rabbitmq_delayed_message_exchange-3.8.9-0199d11c.ez file from the assets section of the release page on GitHub and place the file in the RabbitMQ plugin directory (plugins directory).

Note: The version number may differ from the one in this tutorial. If your RabbitMQ is the latest version, simply choose the latest version of the plugin.

2. Activating the plugin

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

3. Defining the exchange

Set custom exchange properties using x-delayed-type to support sending delayed messages.

props := make(map[string]interface{})
// Key parameter to support sending delayed messages
props["x-delayed-type"] = "direct"

// Declare the exchange
err = ch.ExchangeDeclare(
"delay.queue", // Exchange name
"fanout",      // Exchange type
true,          // Durable
false,
false,
false,
props,         // Set properties
)

4. Sending delayed messages

Set the message delay time using the message header (x-delay).

msgHeaders := make(map[string]interface{})
// Set the message delay time using the message header, in milliseconds
msgHeaders["x-delay"] = 6000

err = ch.Publish(
"delay.queue", // Exchange name
"",            // Routing parameter
false,
false,
amqp.Publishing{
Headers: msgHeaders,   // Set message headers
ContentType: "text/plain",
Body: []byte(body),
})

Note: If you are using Alibaba Cloud's RabbitMQ Message Queue service directly, you can set the delay time using the message header attribute (delay) without installing the plugin. Alibaba Cloud has already extended RabbitMQ for this purpose.