延迟消息是在业务场景中比较常用的功能,可以作为延迟队列。比如订单n分钟未支付自动取消,活动倒计时,定时发消息都可以使用到延迟消息。
一、延迟消息介绍
生产者将消息发送到Broker,消费端不会立即消费,需要到达指定延迟时间才能被消费端消费。RocketMQ的延迟消息,默认支持设置18个延迟等级,每一个等级对应一个延迟时间。在Broker中会创建一个默认的SCHEDULE_TOPIC_XXXX的topic,topic下有18个队列,对应18个延迟等级。消息发送过来,会先把消息存储在topic名字为SCHEDULE_TOPIC_XXXX的队列内,等着延迟时间到了,在转发到目标队列,之后消费者在消费。
由于broker是集群模式部署,每个节点都有18个队列。默认的延迟级别不满足业务需求也可以通过Message.setDelayTimeLevel( )方法进行设置,如下代码所示。
//默认
private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";
//修改成20h
private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 20h";
//新增20h,等级就变成了19
private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h 20h";
二、延迟消息举例
生产者发送消息时,设置Message的DelayTimeLevel字段,设置消息的延迟等级。比如设置DelayTimeLevel=4 延迟等级,则对应的延迟为30s。消费者30s之后可以消费到该消息。
Message msg = new Message(topic, tag, body);
//设置延迟level为4 对应30s。传输对应等级,不传输具体时间限制。
//level设置为0表示不延迟
msg.setDelayTimeLevel(level);
三、延时消息实现原理
RocketMQ延迟消息在Broker内部流程图:
步骤说明:
1.Broker接收到写入的消息,先将目标Topic和队列信息存储到消息的属性(Message对象内的