TL;DR

  • 场景:用 RocketMQ 做订单、支付、库存等分布式链路,关注一致性、可靠性、可恢复与抗压
  • 结论:关键能力集中在顺序消费、Broker 端过滤、事务消息、延迟投递、重试/死信与流控边界
  • 产出:一份可直接放进”RocketMQ 特性”章节的结构化说明 + 默认值/版本敏感点与错误速查卡

RocketMQ特性

订阅发布

消息的发布是指某个生产者向某个Topic发送消息,消息的订阅是指某个消费者关注了某个Topic中带有某些Tag的消息。

消息顺序

消息有序是指一类消息消费时,能按照发送的顺序来消费,例如:一个订单产生了三条消息分别是订单创建、订单付款、订单完成。消费时要按照这个顺序消费才能有意义,但是同时订单之间是可以并行消费的,RocketMQ 可以严格的保证消息有序。

消息过滤

RocketMQ的消费者可以根据Tag进行消息过滤,也支持自定义属性过滤,消息过滤目前是在Broker端实现的,优点是减少了对于Consumer无用消息的网络传输,缺点是增加了Broker的负担、而且实现相对复杂。

消息可靠性

RocketMQ支持消息的高可靠,影响消息可靠性的几种情况:

  1. Broker 非正常关闭
  2. Broker 异常宕机
  3. OS 异常宕机
  4. 机器掉电,但是能立马恢复供电
  5. 机器无法开机
  6. 磁盘设备损坏

其中情况1-4都属于硬件资源可以恢复,RocketMQ在这四种情况下能保证消息不丢,或者丢失少量数据。情况5、6属于单点故障,且无法恢复。

RocketMQ 通过异步复制,可保证99%的消息不丢失,但仍然会有极少的消息可能丢失。通过同步双写技术可以完全避免单点。

至少一次

至少一次 At Least Once 指的是每个消息必须投递一次,Consumer先Pull消息到本地,消息完成后,才向服务器返回ACK,如果没有消费一定不会ACK消息,所以RocketMQ可以很好的支持此特性。

回溯消费

回溯消费是指消费者(Consumer)已经成功消费的消息,由于业务需求需要重新消费时,Broker提供的一种消息重放机制。

事务消息

RocketMQ 事务消息(Transactional Message)是一种特殊的消息机制,它能够将应用本地事务和消息发送操作绑定到一个全局事务中,确保这两个操作要么同时成功,要么同时失败。

工作原理

  1. 半消息阶段

    • 生产者发送”半消息”(PREPARED状态)到Broker
    • Broker将消息存入特殊队列,此时消费者不可见
  2. 本地事务执行

    • 生产者执行本地事务
    • 根据本地事务结果提交或回滚事务消息
  3. 事务状态确认

    • 成功:Broker将消息转为可消费状态(COMMIT_MESSAGE)
    • 失败:Broker丢弃该消息(ROLLBACK_MESSAGE)
  4. 状态回查机制

    • 若生产者未及时确认状态,Broker会主动回查事务状态
    • 默认回查次数为15次,间隔时间可配置

定时消息

定时消息(延迟队列)是指消息发送到Broker后,不会立即被消费,等待特定时间投递给真正的Topic。

Broker 有配置项 MessageDelayLevel,默认值为:

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

一共18个等级。

消息重试

Consumer消费消息失败后,要提供一种重试机制,令消息再消费一次。Consumer 消费消息失败通常可以认为有以下几种情况:

  1. 由于消息本身的原因,例如反序列化失败
  2. 由于依赖的下游应用服务不可用,例如db连接不可用

消息重投

生产者在发送消息时:

  • 同步消息失败会重投
  • 异步消息有重试
  • oneway没有任何保证

消息重投保证消息尽可能发送成功,不丢失,但可能会造成消息重复。

流量控制

  • 生产者流控:因为Broker处理能力达到瓶颈
  • 消费者流控:因为消费者能力达到瓶颈

生产者流控

  • commitLog 文件被锁时间超过 osPageCacheBusyTimesOutMills时,发生流控
  • Broker通过拒绝send请求方式实现流量控制

消费者流控

  • 消费者本地缓存消息超过 pullThresholdForQueue时,默认1000
  • 消费者本地缓存消息大小超过 pullThresholdSizeForQueue时,默认100MB

死信队列

死信队列是消息队列系统中用于处理无法被正常消费消息的重要机制。

  1. 当消费者首次处理某条消息失败时,消息队列会自动将该消息标记为”重试状态”
  2. 消息队列会根据配置的重试策略进行多次重试
  3. 当达到预设的最大重试次数后仍消费失败,系统会判定该消息为”死信消息”
  4. RocketMQ中死信队列命名规则:%DLQ% + 消费者组名

错误速查

症状根因定位修复
订单消息没有按顺序消费同一业务键未落到同一队列/顺序消费未启用看生产端路由、消费端顺序模式固定路由到同队列、使用顺序消费
Tag 过滤不生效订阅表达式/Tag 写法错误对比 Producer Tag 与订阅表达式规范 Tag、统一 Topic 语义
消费失败后疯狂重试失败类型不可恢复却走了快速重试看失败堆栈类型、重试间隔不可恢复错误直接丢弃
出现重复消费导致数据错乱生产端重投/网络抖动导致重复投递统计同业务键重复次数业务侧幂等
DLQ 积压快速增长最大重试次数耗尽仍失败看 DLQ 消息量、失败类型建立 DLQ 处理作业
事务消息长期卡住本地事务未正确提交/回滚看事务监听器返回值保证本地事务与状态可判定