If you want messages to be consumed with a delay, you can use the delayed message feature of Message Queue for RabbitMQ. Message Queue for RabbitMQ natively supports the delayed message feature. Compared with open source RabbitMQ, Message Queue for Apache RabbitMQ provides a delayed message feature that is easier-to-use.
What is a delayed message?
A delayed message is a message that is consumed in a specified period of time after it is sent by a producer.
Delayed messages are used in the following scenarios:
- A time window between message production and consumption is required. For example, when an order is created on an e-commerce platform, a producer sends a delayed message to the Message Queue for RabbitMQ broker. The message is used to ask a consumer to check whether the order is paid within a required period of time. If the order is unpaid, the consumer closes the order. The Message Queue for RabbitMQ broker delivers the message to the consumer 30 minutes after the broker receives the message. After the consumer receives the message, it checks whether the payment is complete. If the payment is not complete, the consumer closes the order. Otherwise, the consumer ignores the message.
- Messages are used to trigger scheduled tasks. For example, you can use a delayed message to trigger a scheduled task that sends notifications to users.
- The value of the delay period for a message must be a non-negative integer. Unit: milliseconds.
- The maximum delay period is 86,400,000 milliseconds, which are equal to one day. If the delay period for a message is set to a value larger than the allowed maximum value, the message is processed as a normal message.
Comparison of implementation methods
The following table compares the implementation methods of the delayed message features that are supported by Message Queue for RabbitMQ and open source RabbitMQ.
|Method||Open source RabbitMQ||Message Queue for RabbitMQ|
|Dead-letter exchange and message time-to-live (TTL) of a queue||✔️||✔️|
|Dead-letter exchange and TTL of a message||✔️||✔️|
|Open source delayed message plug-in||✔️||✔️|
|Native delayed message feature of Message Queue for RabbitMQ (recommended)||✖||✔️|
Native delayed message feature of Message Queue for RabbitMQ
- A producer sends a message that is configured with the delay attribute to an exchange.
- The exchange routes the message to a queue.
- A consumer can consume the message from the queue only after the period of time that is specified by the delay attribute elapses.
Best practices of the native delayed message feature
- Producer client
The native delayed message feature of Message Queue for RabbitMQ is easy to use. You need only to set the delay attribute for a message that is sent from the producer client.
The following provides sample code on sending delayed messages in Java:
Map<String, Object> headers = new HashMap<>(); headers.put("delay", "5000");// Indicates that the delay period for the message is 5,000 milliseconds. AMQP.BasicProperties props = new AMQP.BasicProperties.Builder().messageId(UUID.randomUUID().toString()).headers(headers).build();
For more information about sample code in other programming languages, see AMQP Demos.
- Consumer client
To ensure that delayed messages can be immediately delivered to a consumer after the specified delay, we recommend that you use the basic.consume method in push mode instead of the basic.get method in pull mode when you consume messages. Message Queue for RabbitMQ stores messages in distributed mode. If you use the basic.get method in pull mode to obtain messages, you may reach a node where the messages are not stored.
Open source delayed message plug-in
To align with open source RabbitMQ, Message Queue for RabbitMQ is compatible with the open source delayed message plug-in based on the native delayed message feature and frees you from installing the plug-in. To use the open source delayed message plug-in, perform the following operations:
- Declare an exchange of the
x-delayed-messagetype and set the x-delayed-type extended attribute of the exchange to specify the routing rule. Sample code:
Map<String, Object> args = new HashMap<String, Object>(); args.put("x-delayed-type", "direct"); channel.exchangeDeclare("ExchangeName", "x-delayed-message", true, false, args);The following table describes the parameters.
Parameter Description x-delayed-type The type of the exchange. This parameter is used to specify the routing rule. Valid values:
ExchangeName The name of the exchange.Note Make sure that the declared exchange has been created. For more information, see Manage exchanges. x-delayed-message Specifies the exchange type to route the delayed message.
- Send the delayed message. Add a header attribute in the key-value format for the message and specify that the message is
sent to the exchange that is declared in the previous step. In the key-value pair
of this header attribute, the key is x-delay and the value is the number of milliseconds. Sample code:
byte messageBodyBytes = "delayed payload".getBytes("UTF-8"); Map<String, Object> headers = new HashMap<String, Object>(); headers.put("x-delay", 5000);// Indicates that the delay period for the message is 5,000 milliseconds. AMQP.BasicProperties.Builder props = new AMQP.BasicProperties.Builder().headers(headers); channel.basicPublish("ExchangeName", "", props.build(), messageBodyBytes);
Why is the actual delay longer than the specified delay?
The consumer client uses the basic.get method in pull mode to consume messages. Message Queue for RabbitMQ messages are stored in clusters. When a consumer is routed to a Message Queue for RabbitMQ broker by using the basic.get method in pull mode, the consumer may not receive messages from other brokers immediately after the specified delay.