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

RocketMQ如何防止消息丢失?


文章目录

  • 引言
  • 生产端:确保消息成功发出去
  • 存储端(Broker):确保消息持久化且不丢失
  • 消费端:确保消息处理完再确认
  • 总结

引言

大家好!我们使用消息队列中间件的时候,一般都会涉及到消息丢失怎么兜底的问题。今天我们一起来探讨一下RocketMQ是如何帮我们解决这个问题的,同时这也是面试常问的问题。
作为一个后端开发人员,你肯定知道在分布式系统中,性能数据一致性(可靠性)往往是需要权衡的。RocketMQ 想要实现“消息零丢失”,必须在生产存储消费这三个阶段都进行严格的把控。

生产端:确保消息成功发出去

在发送端,主要通过确认机制重试机制来保证。

  • 使用同步发送 (Sync Send):

    • 机制:生产者发送消息后,会阻塞等待 Broker 的响应。只有收到SEND_OK状态,才算发送成功。
    • 处理:如果收到FLUSH_DISK_TIMEOUTFLUSH_SLAVE_TIMEOUT或者SLAVE_NOT_AVAILABLE,虽然消息可能已经到了 Broker,但持久化或同步可能存在风险。严格场景下,需要根据业务决定是否重试。
    • 代码层:不要使用sendOneway(单向发送,不关心结果),也不要过度依赖sendAsync(除非回调处理极其完善)。
  • 失败重试 (Retry):

    • RocketMQ 客户端默认自带重试机制。如果网络抖动导致发送失败,Producer 会自动重试(默认 2 次)。
    • 你可以配置retryTimesWhenSendFailed
  • 事务消息 (Transactional Message):

    • 场景:解决“本地事务执行成功,但消息发送失败”导致的数据不一致问题。
    • 机制:利用 RocketMQ 的半消息(Half Message)机制,实现类似 2PC(两阶段提交)的效果,确保本地数据库更新消息发送是原子操作。

存储端(Broker):确保消息持久化且不丢失

这是最关键的环节,主要涉及刷盘策略主从复制

  • 刷盘策略:同步刷盘 (SYNC_FLUSH)

    • 默认 (Async):消息写入内存 (PageCache) 即返回成功,由 OS 决定何时写入磁盘。如果机器断电,内存数据会丢失。
    • 零丢失配置:flushDiskType设置为SYNC_FLUSH
    • 效果:消息必须真正写入物理磁盘(CommitLog)后,Broker 才会给 Producer 返回成功。
    • 代价:写入吞吐量会大幅下降。
  • 复制策略:同步复制 (SYNC_MASTER)

    • 默认 (Async):Master 收到消息即可,后台异步同步给 Slave。如果 Master 宕机且磁盘损坏,未同步的消息会丢失。
    • 零丢失配置:brokerRole设置为SYNC_MASTER
    • 效果:Master 收到消息后,必须等待 Slave 也成功写入,才会给 Producer 返回成功。
    • 代价:增加了网络往返延时,可用性略有降低(Slave 挂了可能影响写入)。
  • 高可用架构:DLedger (Raft 协议)

    • RocketMQ 4.5+ 引入了基于 Raft 协议的 DLedger 存储模式。它不仅解决了自动故障切换(Failover),还通过 Raft 的强一致性保证数据不丢失(只要大多数节点存活,数据就在)。

如果不启用Dledger或者同步刷盘(性能下降),我们需要保证异步刷盘和消息不丢失,需要引入本地消息表模式(或称为最大努力通知模式)。
本地消息表的核心思想是:将本地数据库事务消息发送绑定在一起,以确保它们要么同时成功,要么同时失败

在这个模式下,Broker 即使宕机,消息也不会丢失,原因在于:

  1. 保障机制:消息的“生命”已经从 RocketMQ Broker 转移到了生产者的本地数据库中。只要本地事务提交成功,消息就安全了。
  2. 性能提升:Broker 即使是ASYNC_FLUSH异步刷盘,也只影响 Broker 侧的持久化风险,不影响您的业务事务。您将消息记录到本地数据库,这个操作是快速的本地事务,对性能影响小。
  3. 最终一致性:引入一个独立的定时任务:它会定时扫描本地消息表中状态为待发送发送失败的记录,并重新投递给 RocketMQ

消费端:确保消息处理完再确认

消费者端主要防止“消息拿到了,但在业务逻辑处理完之前程序挂了,导致消息被认为已消费”。

  • 手动 ACK 机制 (At-Least-Once):

    • RocketMQ 默认就是“先处理业务,后 ACK”。
    • 关键点:只有当你的业务逻辑(比如写库、调用下游接口)完全执行成功后,才返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS
    • 异常处理:如果业务抛出异常,或者返回RECONSUME_LATER,Broker 会接管该消息,放入重试队列,稍后再次投递。
  • 死信队列 (DLQ):

    • 如果消息重试了 16 次(默认)依然失败,会被放入死信队列,不会被丢弃。你需要建立监控机制,人工介入处理死信队列中的消息。

这里记得处理幂等性问题噢❤️,(如使用数据库唯一键、Redis 去重等),这是实现消息可靠性的另一面硬币。

总结

好的我们从三个方面分层分析了RocketMQ是如何保证消息不丢失的。

对于消息队列的这些消息问题,我们一般都是要从这三方面去考量噢,面试最好也是这样分层次给面试官回答,这样印象分会大大增加❤️

http://www.rkmt.cn/news/94443.html

相关文章:

  • 009.数组排序
  • JavaEE:多线程基础,多线程的创建和用法 - 实践
  • 8051U深度入门到32位51大型实战
  • 吐血整理,装修前的灵魂拷问!口碑炸裂的装修公司大盘点 - 品牌测评鉴赏家
  • Claude提示工程核心技巧与程序员实战指南
  • renren-fast-vue 企业级后台管理系统开发实战指南
  • 面试手撕排序
  • 800+高质量Unity材质球:游戏开发的视觉宝藏
  • 基于深度学习的木薯病害检测系统演示与介绍(YOLOv12/v11/v8/v5模型+Pyqt5界面+训练代码+数据集)
  • 考研路茫茫――单词情结
  • 二手房翻新不踩坑!2025年这些靠谱公司帮你焕新家 - 品牌测评鉴赏家
  • 2025苏州毛坯房装修攻略:这5家专业公司让毛坯变美宅不踩坑 - 品牌测评鉴赏家
  • 风-储系统仿真模型;通过模糊逻辑控制策略驱动蓄电池变换器运行,以达到为电网提供惯量的目的
  • 003HTML
  • 全包装修不踩坑!2025年高性价比装企测评指南(附业主真实踩坑避坑攻略) - 品牌测评鉴赏家
  • JavaEE进阶——SpringAOP从入门到源码全解析
  • 木材碳封存技术:应对气候变化的低科技方案
  • SCCLIP
  • Flutter 与 OpenHarmony 深度整合:构建跨设备统一通知中心系统
  • NSmartProxy:一款.NET开源、跨平台的内网穿透工具
  • Flutter 与 OpenHarmony 深度整合:构建跨设备统一剪贴板同步系统
  • 「旅行商问题 TSP 动态规划 贪心算法 数据结构 Java 代码」
  • java 设置日期返回格式的几种方式
  • SolidWorks装配体与装配图区别介绍
  • JAVA 中dao层的实体应该属于哪个层次VO,还是DTO,或者其他
  • 基于ADM自适应增量调制算法的Matlab性能仿真 - 功能介绍及操作指南(Matlab 20...
  • java学习日志--API文档的小白使用介绍
  • PMC政策文本量化评估
  • 基于Plecs仿真的全桥PSFB移相技术:375V输入,48V输出,2.5kw功率传输的电源系...
  • DETR模型融合终极指南:3步打造高稳健性目标检测系统