news 2026/4/18 12:58:47

RocketMQ延迟消息实现原理解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RocketMQ延迟消息实现原理解析

一、核心原理概述

RocketMQ的延迟消息实现采用"预置延迟等级 + 定时扫描转发"的机制,并非真正的实时延迟,就是通过预定延迟等级将消息暂存到特定队列,等待时间到达后再投递给消费者。

1. 实现方式

RocketMQ 将延时消息转换为普通消息,通过SCHEDULE_TOPIC_XXXX主题进行分级存储和消费。

2. 延迟级别

RocketMQ 一共支持18个等级的延迟投递,具体时间如下:

投递等级(delay level)延迟时间投递等级(delay level)延迟时间
11s106min
25s117min
310s128min
430s139min
51min1410min
62min1520min
73min1630min
84min171h
95min182h
// RocketMQ预定义的18个延迟等级 private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h"; // 对应18个SCHEDULE_TOPIC_XXXX队列

3. 整体流程

二、核心实现步骤

发送阶段

java // 生产者发送延迟消息 Message msg = new Message("TestTopic", "Hello RocketMQ".getBytes()); // 设置延迟级别(对应上面级别的索引,从1开始) msg.setDelayTimeLevel(3); // 延迟10秒 producer.send(msg);

内部转换流程

  1. 消息标记:Broker 收到延迟消息后,将原 Topic 和 QueueId 存入消息属性

  2. 主题切换:将消息的实际 Topic 改为SCHEDULE_TOPIC_XXXX

  3. 队列分配:根据延迟级别分配到对应的延迟队列

    • 延迟级别1 → SCHEDULE_TOPIC_XXXX 的 Queue 0

    • 延迟级别2 → SCHEDULE_TOPIC_XXXX 的 Queue 1

    • ...

    • 每个延迟级别对应一个专门的队列

定时扫描机制

java // 简化后的处理逻辑 class ScheduleMessageService { // 定时任务,每秒执行一次 (实际会根据延迟级别进行分级延迟扫描) public void start() { for (int level = 1; level <= maxDelayLevel; level++) { // 计算当前级别对应的延迟时间 long delayTime = computeDeliverTimestamp(level); // 扫描对应队列中到期的消息 scanAndDeliver(level, delayTime); } } }

消息投递

  1. 扫描到期消息:每个延迟队列有独立的定时任务,按时间轮询扫描

  2. 恢复原主题:从消息属性中取出原始 Topic 和 QueueId

  3. 重新投递:将消息存入原始 Topic 的 CommitLog

  4. 消费者消费:消费者从原始 Topic 正常消费消息

三、 存储结构

四、Broker核心处理流程

五、 限制与改进

配置延迟级别

properties # broker.conf messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

重要限制

  1. 固定延迟级别:不支持任意时间延迟,只能使用预设级别

  2. 时间精度:秒级精度

  3. 最大延迟:默认最长2小时(可配置)

  4. 消息顺序:延迟消息会破坏严格的消息顺序

5.0+ 版本改进

RocketMQ 5.0 引入了TimerWheel(时间轮)优化:

  • 支持任意时间延迟(毫秒级精度)

  • 更高的性能,O(1) 时间复杂度

  • 支持更长的延迟时间(数天级别)

最佳实践

java // 最佳实践 public class DelayMessageExample { public void sendDelayMessage() { Message msg = new Message("OrderTopic", "订单超时取消".getBytes()); // 根据业务需求选择合适的延迟级别 // 订单超时:30分钟 → level 16 // 支付提醒:15分钟 → 可选择10m或20m级别 msg.setDelayTimeLevel(16); // 30分钟 // 消息去重:延迟消息可能需要配合唯一Key msg.setKeys("ORDER_123456"); producer.send(msg); } }

总结

RocketMQ 延迟消息通过"主题转换 + 分级延迟队列 + 定时扫描"实现,虽然不支持任意时间点延迟,但满足了大多数业务场景(如订单超时、定时提醒等)。对于更灵活的延迟需求,可考虑升级到 5.0+ 版本或使用时间轮实现。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 2:05:23

【电动机】液压伺服电动机的状态空间设计与Matlab仿真

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1…

作者头像 李华
网站建设 2026/4/18 6:24:13

Java小白面试:从Spring Boot到微服务与云原生的逐步提升

Java小白求职者面试实战&#xff1a;从Spring Boot到微服务与云原生 场景&#xff1a;一家知名互联网大厂的面试 面试官&#xff1a;欢迎来到我们的面试&#xff0c;超好吃。今天我们会根据一些实际场景&#xff0c;测试你的技术能力。放松&#xff0c;尽力回答就好。 第一轮&a…

作者头像 李华
网站建设 2026/4/18 6:26:16

ClickHouse 集群部署指南:构建高可用大数据分析平台

ClickHouse 集群部署指南&#xff1a;构建高可用大数据分析平台 1. 引言&#xff1a;为什么需要ClickHouse集群&#xff1f; ClickHouse作为列式存储分析型数据库的标杆产品&#xff0c;以其亚秒级查询性能、海量数据存储能力和线性扩展特性&#xff0c;成为互联网、金融、电…

作者头像 李华
网站建设 2026/4/18 7:56:09

解决word分栏问题

“Word分为左右两版”通常有两种情况&#xff1a;一种是你故意设置了分栏排版&#xff08;像报纸那样&#xff09;&#xff0c;想要恢复或调整&#xff1b;另一种是你无意中触碰了设置&#xff0c;导致视图显示变成了两页并排。为了帮你彻底解决这个问题&#xff0c;我将针对这…

作者头像 李华
网站建设 2026/4/18 10:49:54

PE之代码解析资源表

PE之代码解析资源表 1)资源表 资源表(ResourceTable)是PE(PortableExecutable)文件格式中用于存储程序运行所需各类资源的核心结构比如图标,字符串,对话框,位图,菜单,版本信息等。这些资源以树形结构组织,是PE文件可选头(OptionalHeader)中数据目录表(DataDirectory)…

作者头像 李华
网站建设 2026/4/18 8:20:45

计算机Java毕设实战-基于SpringBoot的水族馆商品销售与经营管理系统基于vue的水族馆观赏鱼商品销售与经营管理系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华