RocketMQ 消息类型

消息类型

RocketMQ 的消息按「有没有特殊语义」分成四类:

类型 一句话
普通消息 无特殊语义,最常用
顺序消息 保证同一队列内按发送顺序消费
事务消息 保证「本地事务 + 发消息」的最终一致性
延时消息 指定延时时间后才投递

一、普通消息

是什么:没有特殊语义的消息,最常用的一类。

三种发送方式(重点):

发送方式 特点 适用场景
同步发送 syncSend 阻塞等待 Broker 返回结果 重要消息,必须确认发出去了
异步发送 asyncSend 不阻塞,通过回调拿结果 对响应时间敏感,也要知道结果
单向发送 sendOneWay 发出去就不管,不关心结果 日志、埋点这类丢了无所谓的

怎么选 :就看你要不要知道发送结果------要就同步 / 异步,不要就单向。

消费模式 :默认是并发消费(多个线程并行处理同一个队列里的消息),不保证顺序。


二、顺序消息

解决什么问题:同一业务实体的多条消息,必须按发送顺序处理。

例子:一个订单的「创建 → 支付 → 发货」,如果消费顺序乱了,会出现「先发货后支付」。

实现原理(生产端和消费端要配合):

端 做什么
生产端 用 MessageQueueSelector,把同一个业务 Key (如订单 ID)的消息发到同一个 Queue
消费端 用 MessageListenerOrderly,对该队列加锁串行消费

关键限制 :RocketMQ 只保证「同一个 Queue 内 」有序,不保证全局有序。

两种粒度:

粒度 做法 评价
全局有序 一个 Topic 只设一个 Queue 性能极差,基本不用
分区有序 同一业务 Key 进同一个 Queue 推荐做法

代价 :顺序消费是串行的,并发度下降,吞吐低于并发消费。


三、事务消息

解决什么问题 :让「本地事务 」和「发消息」这两件事要么都成功,要么都不做。

典型场景:下单扣库存成功后要发消息通知积分服务。如果扣完库存、发消息失败,数据就不一致了。

核心机制:半消息(Half Message)

sql 复制代码
┌──────────┐          ┌──────────┐          ┌──────────┐
│ Producer │          │  Broker  │          │ Consumer │
└────┬─────┘          └────┬─────┘          └────┬─────┘
     │  ① 发送半消息        │                     │
     │─────────────────────►│                     │
     │                      │ 存入 HALF_TOPIC     │
     │  ② 返回成功           │ (消费者看不到)     │
     │◄─────────────────────│                     │
     │                      │                     │
     │  ③ 执行本地事务       │                     │
     │  ┌────────────┐      │                     │
     │  │  本地事务   │      │                     │
     │  └────────────┘      │                     │
     │                      │                     │
     │  ④ Commit / Rollback │                     │
     │─────────────────────►│                     │
     │                      │ ⑤ 投递到真实 Topic  │
     │                      │────────────────────►│
     │                      │                     │
     │  ⑥ 回查(超时未收到确认)                    │
     │◄─────────────────────│                     │

四个关键点:

  • 半消息 :先发到 Broker,但存在 RMQ_SYS_TRANS_HALF_TOPIC,消费者看不到
  • 本地事务:半消息发成功之后,才执行本地事务
  • Commit / Rollback:按本地事务结果,决定把消息「放出来」还是「删掉」
  • 回查 :Broker 长时间没收到确认,会主动问生产者(checkLocalTransaction)

回查的默认参数:

参数 默认值 含义
transactionTimeOut 6 秒 多久没收到确认就开始回查
transactionCheckInterval 60 秒 回查间隔
transactionCheckMax 15 次 最多回查几次,超过就丢弃

一句话 :事务消息保证的是最终一致 ,不是强一致------它只保证消息最终会被投递或丢弃,不保证消费端一定处理成功。


四、延时消息

是什么 :消息发送后不立即投递,等指定时间后才被消费者拿到。

典型场景:订单超时未支付自动取消、定时提醒。

实现原理:

  1. 消息先发到内部 Topic SCHEDULE_TOPIC_XXXX
  2. Broker 的定时任务扫描,到期的消息才被投递到真实 Topic
  3. 消费者这时才看得到

⚠️ 版本差异(常被问):

版本 支持情况
4.x 开源版 只支持 18 个固定级别:1s、5s、10s、30s、1m、2m、3m、4m、5m、6m、7m、8m、9m、10m、20m、30m、1h、2h
5.0 起 支持任意时间(最大 40 天)

坑:4.x 里想延时 7 分钟做不到,只能选最接近的固定级别(5m 或 10m)。


五、四种类型对比

类型 解决什么 代价 典型场景
普通消息 异步解耦 --- 大部分场景
顺序消息 严格按序处理 并发度下降 订单状态流转、binlog 同步
事务消息 本地事务与发消息的原子性 实现复杂、有回查开销 分布式事务最终一致
延时消息 定时触发 4.x 只支持固定级别 订单超时取消

选型口诀:

  • 只要解耦异步 → 普通消息
  • 同一实体的消息不能乱序 → 顺序消息
  • 本地操作和发消息必须一致 → 事务消息
  • 要「过一会儿再处理」 → 延时消息

六、总结

  • 普通消息:看要不要知道发送结果,决定同步 / 异步 / 单向。
  • 顺序消息:生产端按业务 Key 选 Queue + 消费端加锁串行;只保证单队列有序,代价是并发度下降。
  • 事务消息:半消息 + 本地事务 + Commit/Rollback + 回查;保证最终一致,不保证消费成功。
  • 延时消息:4.x 只有 18 个固定级别,5.0 起才支持任意时间。
相关推荐
高频因子挖掘机3 小时前
批量行情返回后,怎样把请求失败的股票单独挑出来?
后端·github·api
小蒜学长3 小时前
在线保险服务与管理平台的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端·服务平台·在线保险
我的div丢了肿么办4 小时前
go语言中管道 channel的使用
后端·go
Harvil_4 小时前
模型点三道菜,回喂被拒 400
后端
松就是我902985 小时前
如何设计多Agent
后端
高频因子挖掘机5 小时前
盘中筛选要同时看价格和盘口?按需分层比“一次全拿”更好维护
后端·github·api
asong5 小时前
从写代码到部署上线,Cloudflare 给 AI 配了一把新钥匙
前端·javascript·后端
RobinDevNotes5 小时前
PagedAttention原理,KV缓存也能分页
人工智能·后端
卷无止境5 小时前
当AI写代码遇见Rust为什么会卡壳
后端·python