RocketMQ中延迟消息代码实现

166 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情

前言

上一篇文章我们分析了延迟消息的使用场景,这篇文章我们分析一下RocketMQ中对延迟消息的代码实现 其实RocketMQ对延迟消息的支持是很好的,实现起来也非常的容易,这里演示的是阿里云商业版RocketMQ实现ONS的代码示例。

用法

其实发送延迟消息的核心,就是设置消息的delayTimeLevel,也就是延迟级别。
RocketMQ默认支持一些延迟级别如下:1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h 设置延迟级别为3,意思就是延迟10s,你发送出去的消息,会过10s被消费者获取到。
那么如果是订单延迟扫描场景, 可以设置延迟级别为16,也就是对应上面的30分钟
而在阿里云商业版RocketMQ实现ONS的实现里,可以设置任意的时间。只需要在ons封装的Message对象的系统属性K-V对里添加__STARTDELIVERTIMEkey并设置值。
设置消息的定时投递时间(绝对时间),最大延迟时间为7天.
例1: 延迟投递, 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;
例2: 定时投递, 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01 11:30:00").getTime()。

设置消息投递时间的代码如下

/**
 * <p> 设置消息的定时投递时间(绝对时间),最大延迟时间为7天. </p> <ol> <li>延迟投递: 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;</li>
 * <li>定时投递: 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01
 * 11:30:00").getTime()</li> </ol>
 */
public void setStartDeliverTime(final long value) {
    putSystemProperties(SystemPropKey.STARTDELIVERTIME, String.valueOf(value));
}

发送消息的源码如下

public SendResult send(Message message) {
    this.checkONSProducerServiceState(this.defaultMQProducer.getDefaultMQProducerImpl());
    com.aliyun.openservices.shade.com.alibaba.rocketmq.common.message.Message msgRMQ = ONSUtil.msgConvert(message);

    try {
        com.aliyun.openservices.shade.com.alibaba.rocketmq.client.producer.SendResult sendResultRMQ = this.defaultMQProducer.send(msgRMQ);

        message.setMsgID(sendResultRMQ.getMsgId());
        SendResult sendResult = new SendResult();
        sendResult.setTopic(sendResultRMQ.getMessageQueue().getTopic());
        sendResult.setMessageId(sendResultRMQ.getMsgId());
        return sendResult;
    } catch (Exception e) {
        LOGGER.error(String.format("Send message Exception, %s", message), e);
        throw checkProducerException(message.getTopic(), message.getMsgID(), e);
    }
}