2026/1/11 7:48:30
网站建设
项目流程
个人网站怎么建设规划和建设,免费微商城网站建设,东莞做网站-南城信科,国外开发网站文章目录引言生产端#xff1a;确保消息成功发出去存储端(Broker)#xff1a;确保消息持久化且不丢失消费端#xff1a;确保消息处理完再确认总结引言
大家好#xff01;我们使用消息队列中间件的时候#xff0c;一般都会涉及到消息丢失怎么兜底的问题。今天我们一起来探…文章目录引言生产端确保消息成功发出去存储端(Broker)确保消息持久化且不丢失消费端确保消息处理完再确认总结引言大家好我们使用消息队列中间件的时候一般都会涉及到消息丢失怎么兜底的问题。今天我们一起来探讨一下RocketMQ是如何帮我们解决这个问题的同时这也是面试常问的问题。作为一个后端开发人员你肯定知道在分布式系统中性能和数据一致性可靠性往往是需要权衡的。RocketMQ 想要实现“消息零丢失”必须在生产、存储、消费这三个阶段都进行严格的把控。生产端确保消息成功发出去在发送端主要通过确认机制和重试机制来保证。使用同步发送 (Sync Send)机制生产者发送消息后会阻塞等待 Broker 的响应。只有收到SEND_OK状态才算发送成功。处理如果收到FLUSH_DISK_TIMEOUT、FLUSH_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 即使宕机消息也不会丢失原因在于保障机制消息的“生命”已经从 RocketMQ Broker 转移到了生产者的本地数据库中。只要本地事务提交成功消息就安全了。性能提升Broker 即使是ASYNC_FLUSH异步刷盘也只影响 Broker 侧的持久化风险不影响您的业务事务。您将消息记录到本地数据库这个操作是快速的本地事务对性能影响小。最终一致性引入一个独立的定时任务它会定时扫描本地消息表中状态为待发送或发送失败的记录并重新投递给 RocketMQ消费端确保消息处理完再确认消费者端主要防止“消息拿到了但在业务逻辑处理完之前程序挂了导致消息被认为已消费”。手动 ACK 机制 (At-Least-Once)RocketMQ 默认就是“先处理业务后 ACK”。关键点只有当你的业务逻辑比如写库、调用下游接口完全执行成功后才返回ConsumeConcurrentlyStatus.CONSUME_SUCCESS。异常处理如果业务抛出异常或者返回RECONSUME_LATERBroker 会接管该消息放入重试队列稍后再次投递。死信队列 (DLQ)如果消息重试了 16 次默认依然失败会被放入死信队列不会被丢弃。你需要建立监控机制人工介入处理死信队列中的消息。这里记得处理幂等性问题噢❤️如使用数据库唯一键、Redis 去重等这是实现消息可靠性的另一面硬币。总结好的我们从三个方面分层分析了RocketMQ是如何保证消息不丢失的。对于消息队列的这些消息问题我们一般都是要从这三方面去考量噢面试最好也是这样分层次给面试官回答这样印象分会大大增加❤️