RocketMQ源码之延迟消息!

延迟等级

官方默认设置了18个延迟等级。

1
1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

发送延迟消息:

  • 按照默认顺序1-18数字就对应上面的延迟时间。
1
2
3
4
Message msg = new Message(TOPIC, TAG, "OrderID188", "Hello world".getBytes(StandardCharsets.UTF_8));
//设置延迟等级
msg.setDelayTimeLevel(3);
producer.send(msg);

基本原理

延迟消息都会被存储到 RocketMQ 的一个内部 Topic SCHEDULE_TOPIC_XXXX 当中。

SCHEDULE_TOPIC_XXXX 总共有 18 个 MessageQueue:

  • 对应延迟消息的 18 个等级,根据指定的 DelayTimeLevel 来决定选择哪个 MessageQueue。

有一个定时任务,每100ms执行一次判断SCHEDULE_TOPIC_XXXX Topic中的MessageQueue的消息是否到达延迟时间。

到达延迟时间,将 SCHEDULE_TOPIC_XXXX中的消息投递到消息最初需要投递的Topic中。

为什么不支持任意时间?

RocketMQ并不支持任意时间的延迟,个人觉得主要的原因还是因为性能。

如果提供任意时间,就会涉及到消息的排序,会有一定的性能损耗。