持续创作,加速成长!这是我参与「掘金日新计划 · 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);
}
}