当前位置: 首页 > 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.cnnetsun.cn/news/41998.html

相关文章:

  • CSS尺寸、盒子模型、定位、浮动与布局(Flex/Grid)
  • 《构建游戏实时流失预警模型的核心逻辑》
  • 两个步骤,打包war,tomcat使用war包
  • idea修改maven的刷新引入依赖快捷键
  • 纯电动汽车Simulink仿真模型建模详细步骤。 通过文档的形式,跟着文档一步一步操作,既可以...
  • 同花顺平衡多空看图操作多空理论
  • 通达信222222测试帖别下载
  • 通达信大盘个股共振指标公式
  • 这些核心特征,让芯片散料转编带设备成行业刚需
  • ~给媳妇的新称呼~
  • java计算机毕业设计社区服务微信小程序 基于微信生态的社区便民服务平台 SpringBoot+微信小程智慧社区服务系统
  • SynthPose-VitPose终极部署指南:从零到精通的人体姿态估计实战
  • DataEase vs PowerBI:当数据分析遇见选择困难症,你该如何破局?
  • android 之 AAudio
  • anoconda简单操作
  • 多场景头盔佩戴检测
  • 70看看:AI如何帮你快速生成代码项目
  • 13、Puppet 模块与类:从基础到高级应用
  • JBoltAI 识图阅卷:AI 赋能教育考评,开启智能阅卷新时代
  • 16、模板与容器管理:Puppet 实践全解析
  • MinGW-w64实战:从下载到编译第一个C++项目
  • 分享英飞凌晶闸管模块:浪涌防护解决方案
  • 日拱一卒之Wirtinger 导数
  • GG3M 前沿项目:组织架构与核心管理团队解析 | Analysis of Organizational Structure and GG3M Core Management Team
  • 产学研融合:智慧农业的创新密码
  • Visual C++运行库入门指南:从安装到故障排除
  • AI如何帮你解决Visual C++运行库缺失问题
  • 【开题答辩全过程】以 公寓出租系统为例,包含答辩的问题和答案
  • XiaoYao_快速跳转(Windows系统增强小工具)
  • ODS入门指南:零基础搭建你的第一个数据接入层