news 2026/6/23 18:17:42

RocketMQ如何防止消息丢失?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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是如何保证消息不丢失的。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 16:03:16

CSS尺寸、盒子模型、定位、浮动与布局(Flex/Grid)

尺寸单位: px,em,rem,frimg各单位定义px (像素): 相对固定的单位,代表屏幕上的一个物理点。在高分辨率屏幕上,1个CSS像素可能对应多个物理像素。em: 相对单位,相对于父元素的字体大小。如果父元素字体大小为16px,则1em 16px。rem…

作者头像 李华
网站建设 2026/6/23 11:21:12

《构建游戏实时流失预警模型的核心逻辑》

玩家流失预警的关键痛点从来不是捕捉显性的行为衰减,而是解码藏在时序流转里的隐性流失信号—那些散落在跨模块交互、行为节奏变化中的序列异动,往往比单纯的在线时长缩短、任务参与度下降更早暴露玩家的离开倾向,也是实时预警模型能否实现“提前干预、精准留客”的核心突破…

作者头像 李华
网站建设 2026/6/23 19:52:29

两个步骤,打包war,tomcat使用war包

资源代码: https://download.csdn.net/download/hashiqimiya/92455258 如上 了解资源代码: 写了一个controller代码,控制接口对应该运行的函数。 package org.example.testproducttomcatwar;import org.springframework.web.bind.annotat…

作者头像 李华
网站建设 2026/6/23 14:19:12

idea修改maven的刷新引入依赖快捷键

在 IntelliJ IDEA 里,Load Maven Changes 对应的是当你修改 pom.xml 或者依赖后,手动刷新 Maven 项目的操作。你也可以给它自定义快捷键。具体步骤如下:1. 打开快捷键设置Windows/Linux: File → Settings → KeymapmacOS: IntelliJ IDEA → …

作者头像 李华
网站建设 2026/6/23 19:51:17

纯电动汽车Simulink仿真模型建模详细步骤。 通过文档的形式,跟着文档一步一步操作,既可以...

纯电动汽车Simulink仿真模型建模详细步骤。 通过文档的形式,跟着文档一步一步操作,既可以提高自己的建模能力,又可以对整个建模思路进行借鉴,形成设计能力。 附带模型。纯电动汽车仿真模型在Simulink里搭建就像搭乐高——找准核心…

作者头像 李华
网站建设 2026/6/23 19:48:46

同花顺平衡多空看图操作多空理论

{}多空:50,COLORFFFFFF,POINTDOT; J:(C-LLV(L,9))/(HHV(H,9)-LLV(L,9))*100,colormagenta; K:SMA(J,3,1),colorwhite; D:SMA(K,3,1),coloryellow; 动能:100 * (LLV(LOW,60)-EMA(CLOSE,3))/(LLV(LOW,60)-HHV(HIGH,60)),colorligray,LINETHICK2; 多:IF(动能>多空,动能,DRAWNUL…

作者头像 李华