Delayed messages let you control when a message becomes available for consumption. The ApsaraMQ for RocketMQ broker holds a delayed message until a specified delivery time, then releases it to subscribers. Delayed messages are similar to delayed queues.
Common use cases:
Order timeout handling: Cancel an unpaid order after 30 minutes by sending a delayed message that triggers the cancellation logic.
Retry with backoff: Schedule a retry attempt after a fixed delay when an upstream dependency is temporarily unavailable.
Deferred notifications: Send a reminder or follow-up notification after a configurable waiting period.
For concepts and constraints, see Scheduled messages and delayed messages.
Prerequisites
Before you begin, make sure that you have:
The TCP client SDK for Java installed. For details, see Prepare the environment
An ApsaraMQ for RocketMQ instance, a topic, and a consumer group created in the console. For details, see Create resources
An AccessKey pair for your Alibaba Cloud account. For details, see Create an AccessKey pair
(Optional) Logging configured. For details, see Logging settings
How delayed messages work
The producer creates a message and sets a delivery time using
setStartDeliverTime().The broker receives the message and holds it until the specified delivery time.
At the delivery time, the broker releases the message to the topic, making it available for consumers.
| Parameter | Detail |
|---|---|
| Time format | Absolute timestamp in milliseconds (Unix epoch) |
| Minimum value | Must be later than the current time |
| Maximum delay | 40 days from the current time |
Send delayed messages
The only difference from sending a normal message is one method call: msg.setStartDeliverTime(delayTime). This sets the absolute timestamp (in milliseconds) at which the broker delivers the message.
For more examples, see the ApsaraMQ for RocketMQ code library.
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.SendResult;
import java.util.Date;
import java.util.Properties;
public class ProducerDelayTest {
public static void main(String[] args) {
Properties properties = new Properties();
// Retrieve the AccessKey pair from environment variables.
// Make sure ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
properties.put(PropertyKeyConst.AccessKey, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
properties.put(PropertyKeyConst.SecretKey, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// Specify the TCP endpoint.
// Find this value in the TCP Endpoint section of the Instance Details page
// in the ApsaraMQ for RocketMQ console.
properties.put(PropertyKeyConst.NAMESRV_ADDR, "<your-tcp-endpoint>");
Producer producer = ONSFactory.createProducer(properties);
// Call start() once before sending any messages.
producer.start();
Message msg = new Message(
"<your-topic>", // Topic created in the console
"DelayMessageTag", // Tag for consumer-side filtering, similar to a Gmail tag
"Hello MQ".getBytes() // Message body in binary format.
// ApsaraMQ for RocketMQ does not process message bodies.
// Producer and consumer must agree on serialization.
);
// Optional: set a business key for message tracing.
// The key should be globally unique when possible. Use it to query
// or resend messages in the ApsaraMQ for RocketMQ console.
msg.setKey("ORDERID_100");
try {
// Set the delivery time to 3 seconds from now.
// The value is an absolute timestamp in milliseconds.
// The maximum delay that you can specify is 40 days.
long delayTime = System.currentTimeMillis() + 3000;
msg.setStartDeliverTime(delayTime);
// Send the message in synchronous transmission mode.
// If no exception is thrown, the message is sent.
SendResult sendResult = producer.send(msg);
if (sendResult != null) {
System.out.println(new Date() + " Send mq message success. Topic is:"
+ msg.getTopic() + " msgId is: " + sendResult.getMessageId());
}
} catch (Exception e) {
// Handle send failure: log, retry, or persist the message.
System.out.println(new Date() + " Send mq message failed. Topic is:" + msg.getTopic());
e.printStackTrace();
}
// Shut down the producer when the application exits.
// For high-throughput scenarios, keep the producer running and reuse it.
producer.shutdown();
}
}Replace the following placeholders with your actual values:
| Placeholder | Description | Example |
|---|---|---|
<your-tcp-endpoint> | TCP endpoint from the Instance Details page | http://MQ_INST_xxxxx.mq-internet-access.mq-internet.aliyuncs.com:80 |
<your-topic> | Topic name created in the console | DelayTopic |
If you are new to ApsaraMQ for RocketMQ, see the Demo project to set up a working project before sending and receiving messages.
Subscribe to delayed messages
Subscribing to delayed messages works the same way as subscribing to normal messages. No special consumer configuration is required -- the delay logic is entirely on the producer side.
For the consumer sample code, see Subscribe to messages.
Next steps
Scheduled messages and delayed messages: Understand the concepts and constraints behind delayed and scheduled message delivery.