这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
《Java 消息中间件·可靠消息与消费治理》2.3 恰好一次的两种实现与成本
Kafka 事务保证的是「多条记录与位移一起提交或一起回滚」,业务恰好一次保证的是「副作用只发生一次」,两者覆盖的范围不同。本篇实测每条一事务、十条一批事务与非事务发送的耗时,再用一个 read_committed 消费者重放已提交记录,展示事务提交后业务仍然重复的完整链路,并给出两种方案的对照表与成立前提清单。
posts
这里是全站文章的归档入口,下面是按时间倒序排列的全部文章。若想按主题浏览,请从首页的专题分类进入。
Kafka 事务保证的是「多条记录与位移一起提交或一起回滚」,业务恰好一次保证的是「副作用只发生一次」,两者覆盖的范围不同。本篇实测每条一事务、十条一批事务与非事务发送的耗时,再用一个 read_committed 消费者重放已提交记录,展示事务提交后业务仍然重复的完整链路,并给出两种方案的对照表与成立前提清单。
唯一约束、去重表、状态机是三种成本不同的幂等实现,选错一种会在并发或重放时失效。本篇先比较三者的写放大、存储与失效边界,再给出一份完整可运行的 IdempotentConsumer:按业务键串行化、PROCESSING/DONE 状态、失败不记账、TTL 惰性清理、容量硬上限,并用 3000 次重复投递和 16 线程同键并发验证它。
重复不是一种故障,而是四种:生产侧重试、消费者再平衡、位移回退、下游重放。本篇用单节点 Kafka 分别构造四类重复,给出每类的原始输出与可识别特征——位移是否相同、eventId 是否相同、是否留下新的生产者序列号,并据此给出一张排查判据表。最后给出处理账本的最小设计,让四类重复在日志里可被区分。
自动提交提交的是「拉取位置」而不是「处理进度」:一次 close 就把 20 条里没处理的 15 条永久跳过。本机用 40 条消息对照 auto-close、auto-kill 与手动提交三种写法,给出已提交位移、重启后重读范围与源码调用链,并划清提交失败时哪些异常可以重试、哪些必须重新加入消费组。
acks=all 只是必要条件:还要看 min.insync.replicas 是否被副本数钳制、ISR 当时够不够、以及是否发生不干净选举。本篇用一个 controller 加三个 broker 杀掉两任 leader,对照 acks=1 的 100 条静默丢失与 acks=all 的完整保留,再拆开 retries、delivery.timeout.ms 与幂等生产者的边界。
一条消息从 send() 到下游落库要经过生产端、broker、消费端、下游存储四段,每段对「成功」的定义都不同。本篇给出四段责任表与各自的失败模式,并用 8 条消息把一次完整追踪和一次崩溃恢复跑出来,说明「消息不丢」到底停在哪一段,以及三段交接处必须写明的契约。
卷二全 50 篇的完整目录:五部分、15 章、45 节,加序、前言与两个附录。每章标注它回答的那一个问题,并给出三条阅读路径——赶时间只看判据的、要落地一条链路的、准备做演练与验收的,另外标明哪些实验可以跳过、哪些必须亲手做,以及每节末尾那条判据该怎么用。
把这一卷的实验底座写清楚:单节点与三节点集群怎么起、客户端工程怎么配,以及最关键的故障注入口径——stop、kill、pause、改配置四种手段各自模拟什么、ISR 何时收缩、本机实测到多少,还有哪些故障本机做不出来、必须标注为未执行并说明它影响哪一条结论。
《群岛纪元》全球同服后,每日重置到底按 UTC、服务器时区还是玩家本地时区切,直接决定公平性与运营成本。本节比较三种口径,讨论重置窗口键、错过补做、崩溃重试的幂等,以及赛季切换时归档、结算和未领取奖励的兜底,并给出可运行的 dailyreset 包。
把卷三涉及的对象状态集中成表:订单、支付、退款、库存、优惠券、活动、权益、订阅、运营操作各自的合法迁移、触发者、并发约束与终态定义,再给出事件流水的字段设计、三种实现方式的对比、状态机测试方法、退款与对账的状态衔接,以及跨对象约束和设计检查项,方便对照代码逐条核对。
为什么 acks=all、手动提交、事务这三张配置牌各自只对了一半:把端到端可靠性拆成生产、broker、消费、下游四段,逐段说明每段能保证什么、在哪里漏、要付什么代价,以及本卷用哪些可复现的实验和判据把每一段钉死,最后给出三卷的分工与贯穿项目 libraryd-mq 的可靠性需求。
从一次只看 GMV、退款率悄悄翻倍的活动复盘切入,说明交易链路为什么需要支付成功率、履约时长、对账差异率三条指标,以及它们各自的分母。给出计算支付率与退款率、用严格阈值判定达标的 Go 实现与边界测试,并说明单一 GMV 如何掩盖真实亏损。
把全书用到的可运行件集中成一份模板:单节点 docker run、三节点 compose(每个节点显式写全 listeners,这是本机踩过的坑)、Maven 工程 pom、生产者与消费者最小可运行类、指标打点与优雅关闭。全部按 4.3.0 实跑验证过,复制后改端口即可用。
把全书用到的命令按「集群、主题、消费组、日志、副本、压测」六组整理成一页,每条都标注了它在哪一节被实际用过。另附一节端口与 listener 的实战排查——包括本机遇到的两个坑:宿主机端口被别的进程占用、以及 advertised 端口和映射端口不一致导致客户端连维。
把前十四章的实验汇总成一份可以照着执行的验收清单:十二个场景,每个给出可量化的判据、本卷对应的实测证据和结论,并配一份可以直接改造成脚本的检查骨架。另外单独列出五项本机做不出来、因而不算通过的检查,说明它们会带来什么风险、下一卷在什么条件下能补上。
升级 Kafka 时要同时管住三个版本号:broker 二进制、metadata.version 和客户端 jar。这一节把这三者的关系拆开,给出四组客户端与服务端的交叉实测(含 2.5.1 这种跨越多个大版本的老客户端),并用 KIP-848 新消费组协议演示什么叫「硬下界」,最后给出 KRaft 下的滚动升级顺序与回滚边界。
Kafka 的 MBean 有近千个,真正常看的只有十二个。这一节把它们分成 broker、客户端、业务三层,给出本机实测的 JMX 采集步骤——包括镜像里没有 jcmd、JMX_PORT 会被客户端继承、JmxTool 的包名在 4.x 改过这三个坑,并用一次 5 万条的生产与消费演示数字怎么变、阈值怎么定、告警怎么去抖。
副本落后与副本分歧是两件事:落后会自己追上,分歧不会。本节实跑 kafka-replica-verification.sh 得到 max lag 0,用 offsetLag 与 dump-log 的 crc 逐层取证,再手动截断 follower 的段文件,观察 LEO 从 682 回退到 651 并重建,并给出反直觉结论:offsetLag=0 时段文件字节数可以不同。
LAG 是一个差值,但成因至少三种:生产变快、消费变慢、分区倾斜。本节用限速消费者制造 0 到 26821 的积压,连续采样 `--describe` 的三列,给出「HW 是否增长、CURRENT-OFFSET 是否推进、LAG 是否均衡」的三步判定法,并实测 max.poll.interval.ms 超时被踢出组与单条处理慢这两种完全不同的表现。
Kafka 的故障不是一张清单,而是一组会互相触发的链条:磁盘满会让 broker 退出,broker 退出会制造 URP,URP 又可能拖垮写入。本节把 URP、离线分区、脑裂、磁盘满、fd 耗尽、ISR 抖动、controller 不可用七类故障做成「现象→指标→命令→根因」对照表,并实跑 URP、fd 耗尽、controller 切换与一次真实的 ENOSPC。