连载中 6/20

消息不丢(下):Broker 刷盘与消费 ACK

2026-07-31 · 1926 阅读 · 0 评论 · 0 赞

中场休息并不安全

上一篇把消息从生产者安全送到了 Broker,但 Broker 只是「收到了」,离「永远不会丢」还有两道坎:它自己断电怎么办?消费端有没有把活干完?这一篇把后两关补齐。

Broker 第一道坎:刷盘策略

消息到了 Broker 先写入内存(页缓存),再落到磁盘。什么时候落盘,两种策略:

  • 同步刷盘(SYNC_FLUSH):消息真正写到磁盘上,才给生产者返回成功。机器断电,已确认的消息一条不丢。代价是写盘的延迟算进了发送链路,吞吐明显下降;
  • 异步刷盘(ASYNC_FLUSH):写进页缓存就返回成功,由后台线程批量刷盘。性能高得多,但断电瞬间缓存里没落盘的消息就没了——用户收到了「发送成功」,消息却不见了。

RocketMQ 默认异步刷盘,交易类业务要显式改成同步刷盘。Kafka 没有同步刷盘选项,它的思路是靠多副本换安全:一份数据在多台机器的页缓存里,全丢的概率大幅降低,性能还快。

Broker 第二道坎:主从复制

单台 Broker 刷盘刷得再勤,机器整个挂了数据还是没了。所以要有主从复制,又分两档:

  • 同步复制(SYNC_MASTER):主节点等从节点把消息写完,才给生产者返回成功。主挂了,从节点上有全量数据;
  • 异步复制:主节点写完就返回,从节点异步追。主挂的瞬间,还没追上的消息丢失。

Kafka 的对应概念是 acks=all:生产者等所有 ISR(同步副本集合)里的副本都写入才返回,配合 min.insync.replicas=2 和 replication.factor=3,允许坏一台机器不丢数据。

组合矩阵:稳和快的四档位

刷盘 x 复制组合可靠性适用
同步刷盘 + 同步复制最高,单机断电或宕机都不丢订单、支付等核心交易
同步刷盘 + 异步复制防断电,不防主机宕机折中场景,少用
异步刷盘 + 同步复制多机缓存互备,断电窗口小一般业务,性能与安全兼得
异步刷盘 + 异步复制最低,两端都有丢的窗口日志埋点,允许丢

消费端:ACK 时机是最容易踩的坑

消费端的丢法最隐蔽。两种时序:

  • 先提交位移,再处理业务:消费者拉到消息就提交 offset,然后干活。活干到一半进程崩溃,重启后 offset 已经过去了,这条消息再也不会被投递——丢了,而且是悄无声息地丢;
  • 先处理业务,再提交位移:业务成功后再 ACK。崩溃了位移没提交,重启后消息重投——重复消费,但至少没丢。重复用幂等解决(第 7 篇),丢失可没有后悔药。

结论只有一个:宁可重复,不可丢失,永远先干活后确认。Kafka 要把 enable.auto.commit 关掉,业务处理完手动 commitSync;RocketMQ 返回 CONSUME_SUCCESS 才算确认,抛异常或返回 RECONSUME_LATER 都会触发重投。

还要防一种死循环:业务代码有 bug,这条消息永远处理失败,于是永远重投——重投必须有上限(RocketMQ 默认 16 次),耗尽后进死信队列等人工介入,这正是第 11 篇的主角。

消息不丢全链路检查表

环节必须做的
生产端禁用 oneway;检查发送状态/回调异常;核心链路上本地消息表
Broker同步刷盘或 acks=all + min.insync.replicas>=2;同步复制
消费端关自动提交;业务成功后再 ACK;重试有上限,死信有告警
兜底生产-消费对账任务,定期核对两端的业务单号集合

小结

Broker 端靠「同步刷盘 + 同步复制」防天灾,消费端靠「先干活后 ACK」防人祸。三关守下来,消息不丢就有了工程保证——但请清醒:这套组合拳的每一次「确认」,都在制造重复的可能,不丢的代价就是把重复问题放大

下一主角顺理成章:消息不重复——为什么「恰好一次」是营销话术,以及消费幂等的三板斧

503

10 年全栈工程师 · 503咖啡馆主理人

#消息队列#消息不丢#刷盘#同步复制#消费ACK

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞