If you want messages to be consumed with a delay, you can use the native message delay scheme of Message Queue for RabbitMQ. This scheme of Message Queue for RabbitMQ is easier to use than other message delay schemes supported by open source RabbitMQ.

What is a delayed message?

A delayed message is consumed with a specified delay after it is sent by a producer.

Scenarios

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.

Limits

  • The value of the delay for a message must be a non-negative integer. Unit: milliseconds.
  • The maximum delay is 86,400,000 milliseconds, which are equal to one day. If the delay for a message is set to a value larger than the allowed maximum value, the message is considered as a normal message.

Comparison between message delay schemes

The following table compares the message delay schemes supported by Message Queue for RabbitMQ and open source RabbitMQ.

Scheme 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 scheme ✔️ ✔️
Native message delay scheme of Message Queue for RabbitMQ (recommended) ✔️

Native message delay scheme of Message Queue for RabbitMQ

Message Queue for RabbitMQ allows you to set the delay parameter for a message whose delivery you want to delay. Routing process of a Message Queue for RabbitMQ delayed message:
  1. A producer sends a message configured with the delay attribute to an exchange.
  2. The exchange routes the message to a queue.
  3. A consumer can consume the message from the queue only after the period of time specified by the delay attribute elapses.
Notice If you want to use this scheme of Message Queue for RabbitMQ to send delayed messages to a queue, do not configure message TTL for the queue. If message TTL is configured for the queue, the delay attribute does not take effect.

Best practices of the native message delay scheme

  • Producer client

    The native message delay scheme of Message Queue for RabbitMQ is easy to use. You need only to set the delay attribute for a message that will be sent from the producer client.

    Java sample code:

    Map<String, Object> headers = new HashMap<>();
    headers.put("delay", "xx");
    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 scheme

To align with open source RabbitMQ, Message Queue for RabbitMQ is compatible with the open source delayed message plug-in scheme based on the native message delay scheme and frees you from installing the plug-in. To use the open source delayed message plug-in scheme, perform the following operations:

  1. Declare an exchange of the x-delayed-message type and set the x-delayed-type extended attribute of the exchange to specify the routing rule. The following sample code provides an example:
    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:
    • direct
    • fanout
    • topic
    • headers
    • x-jms-queue
    • x-jms-topic
    ExchangeName The name of the exchange.
    Note Make sure that the declared exchange has been created. For more information, see Create an exchange.
    x-delayed-message Specifies the exchange type to route delayed messages.
  2. Send a delayed message. Add a header attribute in the key-value format for the message and specify that the message will be sent to the exchange declared in the previous step. In the key-value pair of this header attribute, the key is x-delay and the value is milliseconds. The following sample code provides an example:
    byte[] messageBodyBytes = "delayed payload".getBytes("UTF-8");
    Map<String, Object> headers = new HashMap<String, Object>();
    headers.put("x-delay", 5000);
    AMQP.BasicProperties.Builder props = new AMQP.BasicProperties.Builder().headers(headers);
    channel.basicPublish("ExchangeName", "", props.build(), messageBodyBytes);

    In this example, the exchange delivers the message to the corresponding queue 5,000 milliseconds after the exchange receives the message.

FAQ

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.