发送延时消息
public class ScheduledMessageProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("delay_producer_group");
producer.setNamesrvAddr("106.15.42.999:9876");
producer.start();
int totalMessageToSend = 100;
for (int i = 0; i < totalMessageToSend; i++) {
Message message = new Message("TopicTest", ("Hello scheduled message " + i).getBytes(StandardCharsets.UTF_8));
// 设置延时等级3,这个消息将在10s后发送(现在只支持固定的几个时间,详情查看delayTimeLevel)
message.setDelayTimeLevel(3);
producer.send(message);
}
producer.shutdown();
}
}
消费消息
public class ScheduledMessageConsumer {
public static void main(String[] args) throws Exception {
// 实例化消费者
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("delay_consumer_group");
consumer.setNamesrvAddr("106.15.42.999:9876");
consumer.subscribe("TopicTest", "*");
// 注册消息监听者
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> messages, ConsumeConcurrentlyContext context) {
for (MessageExt message : messages) {
// Print approximate delay time period
System.out.println("Receive message[msgId=" + message.getMsgId() + "] " + (System.currentTimeMillis() - message.getBornTimestamp()) + "ms later");
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
}
}
验证
消息的消费比存储时间晚10秒。
#### 延时消息的使用场景
比如电商里,提交了一个订单就可以发送一个延时消息,1h后去检查这个订单的状态,如果还是未付款就取消订单释放库存。
延时消息的使用限制
private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";
现在RocketMq并不支持任意时间的延时,需要设置几个固定的延时等级,从1s到2h分别对应着等级1到18 消息消费失败会进入延时消息队列,消息发送时间与设置的延时等级和重试次数有关,详见代码SendMessageProcessor.java