RocketMQ的延迟消息实现机制非常巧妙,其核心是通过多级时间轮 + 定时任务 + 消息重投递来实现的。以下是详细实现原理:


⏰ 一、延迟消息的核心设计

  1. 预设延迟级别(非任意时间)
    RocketMQ不支持任意时间延迟,而是预设了18个固定延迟级别(1-18),每个级别对应固定延迟时间:

    // 源码中的延迟级别定义 (MessageStoreConfig类)
    private String messageDelayLevel = "1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h";
    
  2. 延迟消息处理流程

    设置delayLevel
    到达延迟时间
    生产者发送延迟消息
    Broker接收
    存入SCHEDULE_TOPIC队列
    定时任务扫描
    重投递到真实Topic
    消费者消费

🔧 二、Broker端实现细节

1. 特殊主题存储
  • 所有延迟消息先存入内部主题:SCHEDULE_TOPIC_XXXX
  • 该主题包含 18个队列,每个队列对应一个延迟级别
  • 消息结构包含关键元数据:
    class Message {private String topic;      // 原始主题(如ORDER_TOPIC)private int delayLevel;   // 延迟级别(3=10秒)private long storeTimestamp; // 存储时间戳// ...其他字段
    }
    
2. 时间轮调度器(核心)
public class ScheduleMessageService extends ConfigManager {// 延迟级别对应的Timerprivate final ConcurrentMap<Integer, Timer> timerTable = new ConcurrentHashMap<>(32);// 延迟级别对应的处理队列private final ConcurrentMap<Integer, Long> offsetTable =new ConcurrentHashMap<>(32);
}
  • 每个延迟级别独立Timer:为18个级别分别创建定时器
  • 时间轮算法:使用HashedWheelTimer高效管理延迟任务
3. 消息重投递过程

当延迟时间到达时:

  1. SCHEDULE_TOPIC_XXXX的对应队列拉取消息
  2. 清除消息的delayLevel属性
  3. 将消息写入原始目标Topic
  4. 消费者此时可正常消费

⚡ 三、源码级执行流程

  1. 消息接收(Broker端):

    // DefaultMessageStore.putMessage()
    if (msg.getDelayTimeLevel() > 0) {// 修改Topic为SCHEDULE_TOPIC_XXXXtopic = ScheduleMessageService.SCHEDULE_TOPIC;// 计算目标队列:queueId = delayLevel - 1queueId = ScheduleMessageService.delayLevel2QueueId(msg.getDelayTimeLevel());
    }
    
  2. 定时扫描(每秒执行):

    // ScheduleMessageService.executeOnTimeup()
    for (int level = 1; level <= 18; level++) {long delayTimeMillis = computeDeliverTimestamp(level, storeTimestamp);if (now >= delayTimeMillis) {// 触发重投递deliverDelayedMessage(level);}
    }
    
  3. 重投递关键操作

    MessageExt msgExt = scheduleMessageIterator.next();
    // 恢复原始Topic/Queue
    MessageExtBrokerInner msgInner = rebuildMessage(msgExt);
    // 存入CommitLog(真实Topic)
    PutMessageResult result = defaultMessageStore.putMessage(msgInner);
    

📊 四、延迟级别与时间映射

延迟级别实际延迟时间对应队列ID
11秒queue0
25秒queue1
310秒queue2
430秒queue3
51分钟queue4
182小时queue17

⚠️ 五、使用注意事项

  1. 不支持任意时间延迟
    只能选择预设的18个级别(可通过修改配置扩展级别)
  2. 最大延迟时间限制
    默认最大2小时,修改需调整配置并重启Broker
  3. 精度误差
    实际延迟可能有1-2秒误差(受扫描周期影响)
  4. 资源消耗
    高并发延迟消息会显著增加Broker的CPU负载

🔄 六、生产环境优化建议

  1. 调整扫描频率(平衡精度与CPU)
    # broker.conf
    flushDelayOffsetInterval=1000  # 默认1秒,可调大到3秒
    
  2. 扩展延迟级别
    修改messageDelayLevel配置增加自定义级别:
    messageDelayLevel=1s 5s 10s 30s 1m 2m 5m 10m 30m 1h 2h 6h 12h
    
  3. 监控关键指标
    • ScheduleMessageService_* 开头的指标
    • 延迟队列积压情况(通过Admin CLI查看)

通过这种设计,RocketMQ在保证高性能的同时实现了海量延迟消息的支持。实际测试中,单Broker可处理百万级延迟消息,平均延迟误差控制在秒级以内。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/87398.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/87398.shtml
英文地址,请注明出处:http://en.pswp.cn/web/87398.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

D3 面试题100道之(21-40)

这里是D3的面试题,我们从第 21~40题 开始逐条解答。一共100道,陆续发布中。 🟩 面试题(第 21~40 题) 21. D3 中的数据绑定机制是怎样的? D3 的数据绑定机制通过 selection.data() 方法实现。它将数据数组与 DOM 元素进行一一对应,形成三种状态: Update Selection:已…

PyTorch nn.Parameter理解及初始化方法总结

一、理解 nn.Parameter 本质是什么&#xff1f; nn.Parameter 是 torch.Tensor 的一个子类。这意味着它继承了 Tensor 的所有属性和方法&#xff08;如 .data, .grad, .requires_grad, .shape, .dtype, .device, .backward() 等&#xff09;。它本身不是一个函数或模块&#xf…

【Linux】环境基础和开发工具

Linux 软件包管理器 yum 什么是软件包 在Linux下安装软件, 一个通常的办法是下载程序的源代码, 并进行编译, 得到可执行程序. 但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成软件包(可以理解成windows上的安装程序)放在一个服务器上, 通过包管理器可以很方便…

多模态进化论:GPT-5V图文推理能力在工业质检中的颠覆性应用

前言 前些天发现了一个巨牛的人工智能免费学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 &#x1f680;《多模态进化论&#xff1a;GPT-5V图文推理能力在工业质检中的颠覆性应用》 副标题&#xff1a;2025年实测报告显…

Linux实现一主二从模式

主从复制&#xff1a; 复制概念中分为两类数据库&#xff0c;一类是主数据库&#xff08;master&#xff09;&#xff0c;一类是从数据&#xff08;slave&#xff09;&#xff0c;主 数据库可以进行读写操作&#xff0c;并把写的操作同步给从数据库&#xff0c;一般从数据库是只…

大势智慧亮相第十八届中国智慧城市大会

6月26日-28日&#xff0c;第十八届中国智慧城市大会在武汉盛大举行。本次大会以“数智赋能城市创新协同共治发展蓝图”为主题&#xff0c;汇聚了李德仁、刘经南等八位院士及全国智慧城市领域的专家学者、行业精英&#xff0c;共同探讨行业发展新方向。作为实景三维技术领域领军…

Xbox One 控制器转换为 macOS HID 设备的工作原理分析

Xbox One 控制器转换为 macOS HID 设备的工作原理分析 源代码在 https://github.com/guilhermearaujo/xboxonecontrollerenabler.git 这个工程的核心功能是将 Xbox One 控制器&#xff08;macOS 原生不支持的设备&#xff09;转换为 macOS 可识别的 HID 设备。这里通过分析代…

Notepad++ 复制宏、编辑宏的方法

Notepad具有宏的功能&#xff0c;能够记录当下所有操作&#xff0c;后续只需要一键就可以重复执行&#xff0c;大大减少工作量。 比如我需要把很多文件里面的字符完成替换&#xff0c;那我只需要把替换的过程录制成宏&#xff0c;后续打开文件就可以一键替换了。 但是Notepad的…

Oracle:报错jdbc:oracle:thin:@IP地址:端口:实例名, errorCode 28001, state 99999

报错原因是oracle密码过期&#xff0c;根本解决办法是让密码不再过期&#xff0c;永久有效。具体操作记录一下。 cmd命令行输入&#xff1a; sqlplus / as sysdba修改Oracle密码期限为无限&#xff1a; SQL> ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;SQL&…

Apipost 签约中原消费金融:共建企业级 API 全链路协作平台,推动接口管理与测试智能化升级

随着企业数字化转型的不断深化&#xff0c;API 正在从技术细节演变为业务协作的核心枢纽。特别是在金融行业&#xff0c;微服务架构、系统联动、合规要求等多重因素交织下&#xff0c;接口数量激增、管理复杂度提升、质量保障难度加大。近日&#xff0c;Apipost 与中原消费金融…

AntV L7 之LarkMap 地图

一、安装$ npm install -S antv/l7 antv/larkmap # or $ yarn add antv/l7 antv/larkmap二、引入包import type { LarkMapProps, LineLayerProps } from antv/larkmap; import { LarkMap, LineLayer, Marker } from antv/larkmap;三、config配置const layerOptions:Omit<Lin…

客户案例 | 某新能源车企依托Atlassian工具链+龙智定制开发服务,打造符合ASPICE标准的研发管理体系

客户案例 ASPICE标准已成为衡量整车厂及供应商研发能力的重要标尺。某知名车企在其重点项目研发过程中&#xff0c;面临着ASPICE 4.0评估认证的挑战——项目团队缺乏体系经验、流程规范和数字化支撑工具。 为帮助该客户团队顺利通过ASPICE认证并提升研发合规性&#xff0c;At…

stm32的USART使用DMA配置成循环模式时发送和接收有着本质区别

stm32的USART使用DMA配置成循环模式时发送和接收有着本质区别&#xff0c;不要被网上误导了。发送数据时会不停的发送数据&#xff0c;而接收只有有数据时才会接收&#xff0c;没有数据时就会挂起等待。 一、触发机制的差异‌ ‌发送方向&#xff08;TX&#xff09;——状态驱…

银河麒麟系统上利用WPS的SDK进行WORD的二次开发

目录 1.下载安装包 2.安装WPS 3.获取示例代码 4.编译示例代码 5.完整示例代码 相关链接 1.下载安装包 去wps的官网 https://www.wps.cn/ 下载linux版本。 下载的安装包名称为&#xff1a;wps-office_12.8.2.21176.AK.preload.sw_amd64.deb, 官网有介绍适用于Ubuntu、麒麟…

人工智能之数学基础:如何判断正定矩阵和负定矩阵?

本文重点 正定矩阵和负定矩阵是线性代数中的重要概念,在优化理论、数值分析、统计学等领域有广泛应用。 正定矩阵(负定矩阵) 如上所示,我们可以看到满足上面的性质的时候,我们可以认为矩阵A称为正定矩阵(负定矩阵) 举例: 半正定(半负定) 如果≥或者≤的时候,我们认为矩…

汇编基础介绍——ARMv8指令集(四)

一、CMP 指令 CMP 指令用来比较两个数的大小。在 A64 指令集的实现中&#xff0c;CMP 指令内部调用 SUBS 指令来实现。 1.1、使用立即数的 CMP 指令 使用立即数的 CMP 指令的格式如下。 CMP <Xn|SP>, #<imm>{, <shift>} 上述指令等同于如下指令。 SUBS …

深入剖析 Electron 性能瓶颈及优化策略

Electron 是一个流行的跨平台桌面应用开发框架&#xff0c;基于 Chromium 和 Node.js&#xff0c;使得开发者可以使用 Web 技术&#xff08;HTML、CSS、JavaScript&#xff09;构建跨平台的桌面应用。许多知名应用如 VS Code、Slack、Discord 和 Figma 都采用了 Electron。然而…

Qt的前端和后端过于耦合(0/7)

最近在写一个软件&#xff0c;这个软件稍微复杂一些&#xff0c;界面大概需要十几个&#xff0c;后端也是要开多线程读各种传感器数据。然后鼠鼠我呀就发现一个致命的问题&#xff0c;那就是前端要求的控件太多了&#xff0c;点一下就需要通知后端&#xff0c;即调用后端的函数…

碰一碰发视频源码搭建定制化开发:支持OEM

在移动互联网与物联网深度融合的当下&#xff0c;“碰一碰发视频” 作为一种创新的信息交互方式&#xff0c;正逐渐应用于营销推广、产品展示、社交互动等多个领域。其核心在于通过近场通信技术&#xff08;如 NFC、蓝牙&#xff09;实现设备间的快速连接&#xff0c;无需复杂操…

机器学习文本特征提取:CountVectorizer与TfidfVectorizer详解

一、文本特征提取概述 在自然语言处理&#xff08;NLP&#xff09;和文本挖掘任务中&#xff0c;文本特征提取是将原始文本数据转换为机器学习模型可以理解的数值特征的关键步骤。scikit-learn提供了两种常用的文本特征提取方法&#xff1a;CountVectorizer&#xff08;词频统…