当前位置: 首页 > news >正文

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+ 版本或使用时间轮实现。

http://www.jsqmd.com/news/249923/

相关文章:

  • django-flask基于python的高校在线考试系统设计与实现
  • 架构 CPU SOC 核心板
  • 【计算机毕业设计案例】基于JavaSpribgBoot的水果生鲜团购平台基于SpribgBoot的生鲜团购平台(程序+文档+讲解+定制)
  • 【电动机】液压伺服电动机的状态空间设计与Matlab仿真
  • Java计算机毕设之基于SpribgBoot的每日生鲜电商平台生鲜团购平台基于SpribgBoot的生鲜团购平台(完整前后端代码+说明文档+LW,调试定制等)
  • 解决word分栏问题
  • 「数据获取」全国民用运输机场吞吐量排名(2006-2024)
  • 「数据获取」内蒙古地理基础数据(道路、水系、四级行政边界、地级城市、DEM等)
  • Java毕设项目:基于vue的社区生鲜团购在线管理平台基于SpribgBoot的生鲜团购平台(源码+文档,讲解、调试运行,定制等)
  • 智界·无界:高德开发者生态大会深度观察与技术巡礼
  • 【PID优化】基于粒子群算法的自动发电控制AGC系统 PID参数智能整定,两区域负荷频率控制附matlab代码
  • 学霸同款10个AI论文网站,MBA毕业论文轻松搞定!
  • 【剑斩OFFER】算法的暴力美学——leetCode 515 题:在每个树行中找到最大值
  • 【数据分享】上市公司数据资产(2003-2024年)
  • 计算机Java毕设实战-基于SpringBoot的水族馆商品销售与经营管理系统基于vue的水族馆观赏鱼商品销售与经营管理系统【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 【水果检测】基于计算机视觉的植物果实检测方法研究与Matlab仿真
  • 【数据分享】青海路网数据青海路网分类数据(2025年)
  • 计算机Java毕设实战-基于SpribgBoot的有机食品生鲜团购平台基于SpribgBoot的生鲜团购平台【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 学霸同款MBA必看!8个AI论文平台TOP8测评
  • 智能降重有妙招:8款AI工具提升论文查重效率
  • 4535435434
  • 学霸同款2026 AI论文软件TOP9:MBA开题报告神器测评
  • 链接地址 运行地址 加载地址
  • 【毕业设计】基于JavaSpringBoot的水族馆商品销售与经营管理系统基于SpringBoot的水族馆商品销售与经营管理系统(源码+文档+远程调试,全bao定制等)
  • Java毕设选题推荐:基于SpribgBoot的新鲜蔬果生鲜团购平台基于SpribgBoot的海鲜肉类生鲜团购平台【附源码、mysql、文档、调试+代码讲解+全bao等】
  • PE之代码解析资源表
  • PE之代码解析异常表
  • 【无人机协同车辆】合作无人机-地面车辆包裹拾取的最优负载均衡策略以实现最短完成时间 附matlab代码
  • EDGE估计没有switch到frame的做法
  • 《提示工程架构师解析:游戏开发重视提示工程的战略意义》