All Products
Search
Document Center

ApsaraMQ for RabbitMQ:Delayed messages

Last Updated:Apr 16, 2024

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.

  • If the delayed period that you specify for a delayed message is larger than the maximum delay period allowed for the message, the message is processed as a normal message and immediately delivered to the consumer. The maximum delay periods vary based on instance types. For more information, see Limits on clusters.

  • 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 or 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 provided by ApsaraMQ for RabbitMQ and open source RabbitMQ.

Implementation method

Open source RabbitMQ

ApsaraMQ for RabbitMQ

Dead-letter exchange + Queue-level TTL

Supported

Supported

Dead-letter exchange + Message-level 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 section describes 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 for 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 consumers 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 not reach the node in which the messages are 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. The following 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 in the previous code.

    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 type of the exchange that is used 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 pull messages from other brokers immediately after the specified delay period.