RocketMQ 面试核心知识点总结

一、消息不丢失机制

1. 消息丢失的核心环节

消息链路中 4 个关键丢失风险点,跨网络传输和缓存异步刷盘是主要场景:

2. 生产者端防丢失方案

(1)发送确认机制
发送方式 特点 代码示例
单向发送 效率高,可能丢消息 producer.sendOneway(msg);
同步发送 安全可靠,效率低 SendResult result = producer.send(msg, 20000);
异步发送 安全与效率平衡 producer.send(msg, new SendCallback() {<br>@Override<br>public void onSuccess(SendResult res) {}<br>@Override<br>public void onException(Throwable e) {}<br>});
(2)事务消息机制(RocketMQ 特有)

核心流程:

适用场景:电商订单创建与支付确认等分布式事务场景

3. Broker 端防丢失方案

(1)刷盘机制
  • 同步刷盘(SYNC_FLUSH):写入日志即调用 fsync,消息不丢失但 IO 压力大
  • 异步刷盘(ASYNC_FLUSH):定期刷盘,性能好但断电可能丢缓存消息
  • 核心配置:flushDiskType=SYNC_FLUSH(生产环境推荐)
(2)主从同步机制
集群类型 同步方式 数据安全性 切换逻辑
普通集群 同步 Master(SYNC_MASTER)/ 异步 Master(ASYNC_MASTER) 高(SYNC_MASTER) Master 挂了不自动切换
DLedger 集群 Raft 协议多数派确认 极高 自动选举 Leader,数据一致性优先

关键差异:Kafka Leader 崩溃后新 Leader 以自身数据为准,可能丢失未同步消息;RocketMQ Master 重启后继续同步未同步数据,不丢失

4. 消费者端防丢失方案

  • 核心原则:先处理消息,再提交消费确认

  • 风险场景:异步处理消息时提前返回成功状态

    // 错误示例(可能丢失消息)
    consumer.registerMessageListener((msgs, context) -> {
    new Thread(() -> {
    // 异步处理业务,可能未执行完就返回成功
    }).start();
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    });

    // 正确示例(同步处理)
    consumer.registerMessageListener((msgs, context) -> {
    // 同步处理业务逻辑
    processBusiness(msgs);
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    });

  • 重试机制:未收到确认时 Broker 会重复投递,RocketMQ 通过 Offset,RabbitMQ 通过重新入队

5. 极端场景(MQ 集群全挂)处理

  • 降级方案:生产者发送失败时写入本地缓存(如 Redis、文件)
  • 恢复机制:独立线程循环重试发送缓存消息,MQ 恢复后自动补送

6. 零丢失方案总结(trade-off)

环节 方案 代价
生产者 同步发送 + 重试 降低吞吐
Broker 同步刷盘 + DLedger 集群 IO / 网络负担增加
消费者 同步处理 + 确认 无法异步提升效率
集群故障 降级缓存 增加存储成本

二、消息顺序性保障

1. 核心概念

  • 局部有序:同一业务维度(如同一订单)的消息有序(实际业务常用)
  • 全局有序:整个 Topic 的消息有序(极少场景需要,性能极差)

2. 实现机制(RocketMQ)

两大关键

  1. 生产者:通过分区算法将同业务标识消息写入同一 MessageQueue
  2. 消费者:单个 Consumer 线程对应单个 MessageQueue,串行消费

3. 不同 MQ 对比

MQ 产品 顺序性保障方式 特点
RocketMQ 分区绑定 + 单线程消费 支持局部有序,配置灵活
Kafka 单 Partition 单线程消费 天生支持局部有序
RabbitMQ 单 Queue 对应单 Consumer 经典队列需手动保证绑定关系

三、消息幂等性处理

1. 幂等性定义

  • 多次处理同一消息,业务结果一致(不重复创建订单、不重复扣款)

2. 生产者端幂等

(1)RocketMQ 实现
  • 自动生成唯一messageIdMessageConst.PROPERTY_UNIQ_CLIENT_MESSAGE_ID_KEYIDX
  • Broker 通过该 ID 判断重复消息
(2)Kafka 实现
  • 开启幂等性配置(默认开启),核心机制:
    • PID:生产者唯一标识
    • Sequence Number:每个 PID+Partition 的单调递增序号
    • Broker 仅接收序号 = 当前 SN+1 的消息

3. 消费者端幂等

(1)去重依据(优先级)
  1. 业务唯一标识(推荐):如订单 ID、支付流水号(通过msg.setKey(业务ID)设置)
  2. MQ 内置唯一 ID:messageId(批量 / 事务消息场景可能失效)
(2)实现方式
复制代码
// 伪代码示例
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs) {
    for (MessageExt msg : msgs) {
        String businessId = msg.getKey(); // 订单ID
        // 1.查缓存/数据库判断是否已处理
        if (isProcessed(businessId)) {
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
        // 2.处理业务逻辑
        processBusiness(msg);
        // 3.标记为已处理(缓存/数据库)
        markAsProcessed(businessId);
    }
    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
(3)异常处理
  • 重试队列:重复投递的消息进入重试队列(%RETRY%消费者组名
  • 死信队列:多次重试失败进入死信队列(%DLQ%消费者组名),需手动调整权限后处理

四、消息积压处理

1. 积压风险

  • RocketMQ/Kafka:日志文件过期会删除未消费消息
  • RabbitMQ:经典队列积压严重影响服务端性能

2. 处理方案

(1)临时扩容(快速见效)
  • 核心限制:Consumer 实例数 ≤ MessageQueue 数(RocketMQ/Kafka)
  • 操作步骤:
    1. 增加 Consumer 实例(不超过 Queue 数)
    2. 优化 Consumer 消费逻辑(关闭非核心业务、异步处理非关键步骤)
(2)分流处理(大量积压时)
  • 操作步骤:
    1. 创建新 Topic,配置更多 MessageQueue
    2. 部署临时消费者,仅负责将旧 Topic 消息转存到新 Topic
    3. 新 Topic 部署足够多 Consumer 实例快速消费
    4. 消费完成后恢复正常架构

五、常见面试题及参考答案

1. RocketMQ 如何保证消息不丢失?

  • 生产者:使用同步发送 + 重试机制,关键场景用事务消息
  • Broker:配置同步刷盘 + DLedger 高可用集群
  • 消费者:同步处理消息后提交确认,避免异步提前返回成功
  • 极端情况:降级缓存 + 后台重试发送

2. 如何保证消息的顺序性?

  • 实现局部有序:生产者将同业务标识消息写入同一 MessageQueue,消费者单线程消费单个 MessageQueue
  • 不推荐全局有序:Topic 只配置 1 个 Queue,性能极差,无实际业务价值

3. 如何解决消息重复消费问题?

  • 生产者端:RocketMQ 通过唯一 messageId 去重,Kafka 通过 PID+SequenceNumber 保证幂等
  • 消费者端:基于业务唯一标识(如订单 ID)做幂等处理,通过缓存 / 数据库记录处理状态

4. 消息积压了怎么处理?

  • 短期:增加 Consumer 实例(不超过 Queue 数),优化消费逻辑
  • 长期:创建多 Queue 新 Topic,临时分流积压消息,批量快速消费

5. RocketMQ 的事务消息原理是什么?

  • 两阶段提交:先发送半消息,执行本地事务后再确认 Commit/Rollback
  • 兜底机制:Broker 定期回查本地事务状态,避免事务结果丢失

6. RocketMQ 与 Kafka 在消息安全上的核心差异?

  • 主从同步:RocketMQ Master 挂了不切换,重启后同步未同步数据;Kafka 会选举新 Leader,丢失未同步消息
  • 设计初衷:RocketMQ 源于金融场景,优先数据安全;Kafka 源于日志收集,优先服务可用性
相关推荐
问道飞鱼2 小时前
【大模型学习】大模型应用开发工程师面试核心8问
大数据·学习·面试
观测云2 小时前
阿里云 RocketMQ 4.0 可观测最佳实践
阿里云·云计算·rocketmq
Sanyhem3 小时前
2025 年高频考点与深度追问点
java·面试
xiaolyuh1234 小时前
Kafka、RocketMQ、RabbitMQ 事务消息核心差异对比
kafka·rabbitmq·rocketmq
星辰_mya4 小时前
超时未支付订单之分库分表+定时任务+RMQ延时消息
java·架构·rocketmq
Mixtral8 小时前
2026年春招复盘记录工具测评:告别手动整理,AI自动生成求职总结
人工智能·面试·职场和发展·语音转文字·ai语音转文字
yanyu-yaya13 小时前
前端面试题
前端·面试·前端框架
源代码•宸15 小时前
Leetcode—509. 斐波那契数【简单】
经验分享·算法·leetcode·面试·golang·记忆化搜索·动规
Marshmallowc19 小时前
React 合成事件失效?深度解析 stopPropagation 阻止冒泡无效的原因与 React 17+ 事件委派机制
前端·javascript·react.js·面试·合成事件