All Products
Search
Document Center

ApsaraMQ for RabbitMQ:Delayed messages

Last Updated:Sep 07, 2023

If you want messages to be consumed in a specified period of time, you can use the delayed message feature provided by ApsaraMQ for RabbitMQ. ApsaraMQ for RabbitMQ natively supports the delayed message feature. Compared with open source RabbitMQ, ApsaraMQ for 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.

Use 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 ApsaraMQ for RabbitMQ broker. The message is used to confirm with a consumer whether the order is paid within a required period of time. If the order is unpaid, the consumer closes the order. The ApsaraMQ for RabbitMQ broker delivers the message to the consumer 30 minutes after the broker receives the message. After the consumer receives the message, the consumer 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.

Rules for specifying delay periods

  • The value of the delay period for a message must be a non-negative integer. Unit: milliseconds.

  • The maximum delay period that you can specify is 86,400,000 milliseconds (1 day). If you specify a value larger than the maximum value that is allowed for the delay period of a message, the message is processed as a normal message and is immediately delivered for consumption.

  • If you have specified time-to-live (TTL) for delayed messages, the actual message TTL is calculated by using the following formula: Actual message TTL = min {Message-level TTL, queue-level TTL} + Delay period For more information, see Message TTL.

Comparison between implementation methods

The following table compares the implementation methods of the delayed message features that are supported by ApsaraMQ for RabbitMQ and open source RabbitMQ.

Implementation method

Open source RabbitMQ

ApsaraMQ for RabbitMQ

Dead-letter exchange and the message TTL of a queue

Supported

Supported

Dead-letter exchange and message TTL

Supported

Supported

Open source delayed message plug-in

Supported

Supported

Native delayed message feature (recommended)

Not supported

Supported

Native delayed message feature

ApsaraMQ for RabbitMQ allows you to configure the delay attribute for a message to delay the message. The following items describe the data forwarding process of a native delayed message in ApsaraMQ for RabbitMQ:

  1. A producer sends a message that is 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 that is specified by the delay attribute elapses.

Best practices of the native delayed message feature

  • Producer client

    The native delayed message feature of ApsaraMQ for RabbitMQ is easy to use. You need only to configure the delay attribute for a message that is sent from the producer client.

    The following sample code provides an example on how to send a delayed message in Java:

    Map<String, Object> headers = new HashMap<>();
    headers.put("delay", "5000");// Specifies 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 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 period is reached, we recommend that you use the basic.consume method in push mode instead of the basic.get method in pull mode to consume messages. ApsaraMQ 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 in which the messages are not stored.

Open source delayed message plug-in

To align with open source RabbitMQ, ApsaraMQ for RabbitMQ is compatible with the open source delayed message plug-in. You can use the plug-in to send and receive delayed messages without installing the plug-in. To use the open source delayed message plug-in, perform the following operations:

  1. Declare an exchange of the x-delayed-message type and configure the x-delayed-type extended argument 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 in the preceding statement.

    Parameter

    Description

    x-delayed-type

    The exchange type. This parameter is used to specify the routing rule. Valid values:

    • direct

    • fanout

    • topic

    • headers

    • x-jms-queue

    • x-jms-topic

    ExchangeName

    The exchange name.

    Note

    Make sure that the declared exchange is created. For more information, see Manage exchanges.

    x-delayed-message

    The exchange type to route delayed messages.

  2. Send the delayed message. Add a key-value pair to the headers attribute of the message and specify that the message is sent to the exchange that is declared in the previous step. The key of the key-value pair 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);// Specifies 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);

FAQ

Why is the actual delay period longer than the specified delay value?

The consumer client uses the basic.get method in pull mode to consume messages. Messages in ApsaraMQ for RabbitMQ are stored in clusters. When messages are routed to an ApsaraMQ 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 period.