<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>《Java 消息中间件·可靠消息与消费治理》 · 全书目录与章节索引（50 篇） on PlumePHP</title><link>https://plumephp.com/posts/books/java%E6%B6%88%E6%81%AF%E5%8F%AF%E9%9D%A0/</link><description>Recent content in 《Java 消息中间件·可靠消息与消费治理》 · 全书目录与章节索引（50 篇） on PlumePHP</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Thu, 29 Oct 2026 07:49:00 +0800</lastBuildDate><atom:link href="https://plumephp.com/posts/books/java%E6%B6%88%E6%81%AF%E5%8F%AF%E9%9D%A0/index.xml" rel="self" type="application/rss+xml"/><item><title>《Java 消息中间件·可靠消息与消费治理》附录 B 幂等与事务模板</title><link>https://plumephp.com/java-mq-reliable-appendix-b-idempotent-templates/</link><pubDate>Thu, 29 Oct 2026 07:49:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-appendix-b-idempotent-templates/</guid><description>四份可以直接复制的模板：带唯一约束的去重表、状态机迁移、同库同事务的 outbox 与其 relay、以及消费—处理—生产的事务生产者。每份都标注它解决哪一类重复、在什么位置仍会留下窗口、以及拼在一起时不能混用的边界条件，另附一张按场景选模板的决策表。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》15.3 libraryd-mq 卷二验收</title><link>https://plumephp.com/java-mq-reliable-15-3-acceptance/</link><pubDate>Thu, 29 Oct 2026 07:48:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-15-3-acceptance/</guid><description>把卷二四十五章的实验汇总成十八个验收场景，每条给出可执行的判据、证据章节和结论；另外单独列出十项本机做不出来因而不能算通过的检查，说明各自的风险。文末附一份可以直接改造成脚本的检查骨架、0/1/2 打分口径，以及卷二遗留问题与卷三的分工安排，方便团队评审时直接对照使用。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》附录 A 可靠性配置矩阵</title><link>https://plumephp.com/java-mq-reliable-appendix-a-config-matrix/</link><pubDate>Thu, 29 Oct 2026 07:48:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-appendix-a-config-matrix/</guid><description>生产端、消费端、broker 端三张配置表，每一项只回答两个问题：它保住了什么，代价是什么。附六组看起来没问题、实际互相抵消的危险组合，以及一份可以直接抄走的基线配置。默认值按 Kafka 4.3.0 与 kafka-clients 4.3.0 列出。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》15.2 容量与成本核算</title><link>https://plumephp.com/java-mq-reliable-15-2-cost/</link><pubDate>Thu, 29 Oct 2026 07:46:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-15-2-cost/</guid><description>可靠性每一项配置都有账单：副本数乘存储、acks 乘内部复制流量、保留期乘天数、跨集群乘出网。本篇不谈具体价格，只给可核算的量——一天 1000 万条 1 KiB 消息，三档方案各需要多少 GB·天、多少出网流量，以及故障时才支付的副本重建成本。每一档都标出它能防住哪种故障，以及哪一笔钱其实可以不花。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》14.3 恢复演练与 RTO/RPO</title><link>https://plumephp.com/java-mq-reliable-14-3-drill-rto-rpo/</link><pubDate>Thu, 29 Oct 2026 07:45:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-14-3-drill-rto-rpo/</guid><description>三节点 KRaft 上做一次带流量的完整演练：生产 15000 条、消费者常驻，中途停掉一台 broker。实测故障检测 4 秒、数据面恢复 29 秒、业务面 lag 归零 41 秒，生产者 0 失败。文章把这 41 秒拆成五段，说明哪一段是真 RTO、哪一段是人为停机窗口，并给出可重复的演练脚本要素与判据。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》15.1 可靠性验收清单</title><link>https://plumephp.com/java-mq-reliable-15-1-reliability-checklist/</link><pubDate>Thu, 29 Oct 2026 07:45:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-15-1-reliability-checklist/</guid><description>三十条可靠性检查项，分生产端、消费端、broker 与主题、数据链路、运维演练五组。每一条都给可观测的判据、对应的章节、以及不达标时的修改动作——判据都是「做一件具体的事，看一次结果」，不是「已配置」。五组各自附一节最容易做错的地方，末附打分口径与按边际效率排序的修改顺序。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》14.2 故障注入：消费端崩溃</title><link>https://plumephp.com/java-mq-reliable-14-2-fault-consumer-crash/</link><pubDate>Thu, 29 Oct 2026 07:43:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-14-2-fault-consumer-crash/</guid><description>kill -9 一个处理到一半的消费者，实测重复了 61 条：崩溃时处理到 offset 460，最后提交的是 400，重启从 400 继续。再用 SIGSTOP 冻结进程做对照，发现 10 秒后组里变成「no active members」，恢复后从 offset 0 重读。两次实验证明 session.timeout.ms 保护的是「进程卡住」，不是「进程死掉」。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》14.1 故障注入：broker 宕机</title><link>https://plumephp.com/java-mq-reliable-14-1-fault-broker-down/</link><pubDate>Thu, 29 Oct 2026 07:42:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-14-1-fault-broker-down/</guid><description>三节点集群停掉一台，5 万条消息里 0 条失败，停机那 5 秒的平均延迟只从 5.8 毫秒升到 6.3 毫秒——因为 ISR 在 3 秒内收缩到 2，leader 自动换了人。同一时刻另一个 min.insync.replicas=3 的主题在 740 毫秒内重试三次后被拒。两种结果的区别不在故障，在配置。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》13.3 跨集群复制</title><link>https://plumephp.com/java-mq-reliable-13-3-cross-cluster/</link><pubDate>Thu, 29 Oct 2026 07:41:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-13-3-cross-cluster/</guid><description>跨集群复制是异步的，异步就有延迟、重复和位移错位。本篇在本机用两个单节点集群加 MirrorMaker2 实测：820 条消息 1:1 复制、逐条端到端延迟尾部 70–113 ms、offset-syncs 记录 0→0 与 519→519，并原样贴出一个与 offset-syncs 对不上的 checkpoint 记录，说明切换前为什么必须自己校验位移映射。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》13.2 SASL/ACL 与传输加密</title><link>https://plumephp.com/java-mq-reliable-13-2-sasl-acl/</link><pubDate>Thu, 29 Oct 2026 07:40:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-13-2-sasl-acl/</guid><description>配额管的是速率，认证和授权才管得住身份。本篇在本机单节点上起一个 SCRAM-SHA-256 加 ACL 的 broker，贴出未授权读取的 TopicAuthorizationException、错误密码的 SaslAuthenticationException、以及 topic 放行但 group 被拒的原始异常；并用同一份生产者对照 PLAINTEXT、SSL、SASL 的握手与稳态延迟。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》13.1 多租户与配额</title><link>https://plumephp.com/java-mq-reliable-13-1-multi-tenant-quota/</link><pubDate>Thu, 29 Oct 2026 07:39:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-13-1-multi-tenant-quota/</guid><description>客户端配额让吵闹的邻居变慢，而不是被踢掉。本篇在本机单节点上把 producer_byte_rate 配成 1024 B/s，用同一个 Java 生产者跑配额前后两组对照：385 ms 变成 15943 ms，客户端 produce-throttle-time 平均值 782 ms，16 条消息全部 ack、没有一条被拒；再给出按 client-id、按 user、按前缀与物理隔离的多租户方案。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》12.3 消费端性能调优</title><link>https://plumephp.com/java-mq-reliable-12-3-consumer-tuning/</link><pubDate>Thu, 29 Oct 2026 07:38:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-12-3-consumer-tuning/</guid><description>fetch.min.bytes、fetch.max.wait.ms、max.poll.records 三个参数一起调时，批次不是越大越好。本机用 20 万条固定积压跑四组参数，1MB 组比 100 条组快 1.4 倍，而 8MB 组因为超过单次 fetch 上限，每次等待 1 秒、吞吐掉到二十四分之一。附 poll 延迟 p99 与调参顺序。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》12.2 异步提交的陷阱</title><link>https://plumephp.com/java-mq-reliable-12-2-async-commit-pitfall/</link><pubDate>Thu, 29 Oct 2026 07:37:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-12-2-async-commit-pitfall/</guid><description>commitAsync 返回 void，失败既不抛异常也不改返回值；错误要么被丢弃，要么只能等下一次 poll 才在回调里出现。本机复现了被踢出组后异步提交失败、committed 仍为空的全过程，并对照 commitSync 的异常，附回调线程、阻塞与重入的实测。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》12.1 消费者多线程模型</title><link>https://plumephp.com/java-mq-reliable-12-1-consumer-threading/</link><pubDate>Thu, 29 Oct 2026 07:36:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-12-1-consumer-threading/</guid><description>一个消费者跑满一核、lag 却不降时，加线程有三种写法：每线程一个消费者、一个拉取线程加共享工作池、按分区亲和路由。本机用 4 分区 16 万条消息实测三种模型，贴出吞吐、线程数与逆序次数；结论是保序不贵、跨线程交接贵，池化模型必须把提交点压在处理完成之后。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》11.3 大消息的 claim-check 模式</title><link>https://plumephp.com/java-mq-reliable-11-3-claim-check/</link><pubDate>Thu, 29 Oct 2026 07:35:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-11-3-claim-check/</guid><description>消息里只放 URI、SHA-256 与长度，内容进对象存储，这是大消息的常规出路，但它把一次写入拆成两个系统，失败窗口也随之翻倍。本篇给出最小 claim-check 实现，实测文件被删与校验和不符两条失败路径，演示重试、兜底主题与位移提交的先后顺序。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》11.2 压缩算法选择</title><link>https://plumephp.com/java-mq-reliable-11-2-compression-choice/</link><pubDate>Thu, 29 Oct 2026 07:34:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-11-2-compression-choice/</guid><description>同一批事件，gzip、snappy、lz4、zstd 的压缩比可以差两倍以上，CPU 可以差五倍；批次太小或数据本身不可压时，压缩还会让字节数变大。本篇用同一份真实结构的事件跑四种算法，贴出压缩后字节、发送耗时与 broker 落盘字节，并给出负收益判据。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》11.1 消息大小与批量参数</title><link>https://plumephp.com/java-mq-reliable-11-1-message-size/</link><pubDate>Thu, 29 Oct 2026 07:33:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-11-1-message-size/</guid><description>一条消息要过四层尺寸参数：客户端 max.request.size、批量 batch.size、broker 与 topic 的 message.max.bytes、消费端 fetch 上限。本篇在本机逐级放大消息，记录每一档在哪一层被拦、异常原文与错误码，并实测压缩如何让 2 MiB 消息穿过 1 MiB 的 broker 上限。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》10.3 重分区与历史数据</title><link>https://plumephp.com/java-mq-reliable-10-3-repartition/</link><pubDate>Thu, 29 Oct 2026 07:32:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-10-3-repartition/</guid><description>分区数是 key 映射公式里的模数，改一次就有近一半的 key 要换分区。本篇用 20 000 个 key 算出 4→8、4→5、8→12 的落点变化比例，再跑一遍 6 000 条、3 000 个 key 的桥接迁移与双写切换，验证顺序不丢、条数对得上，并给出位移重置与回滚的检查清单。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》10.2 热点分区与 key 设计</title><link>https://plumephp.com/java-mq-reliable-10-2-hot-partition/</link><pubDate>Thu, 29 Oct 2026 07:31:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-10-2-hot-partition/</guid><description>单调递增的 id 在 Kafka 默认分区器下其实很均匀，12 000 条实测最大分区只有平均值的 1.04 倍；真正打满一个分区的是范围分区器、单个热 key 和错误的加盐。本篇用六组 12 000 条实验量出 12 倍、10.9 倍、2.85 倍的分布，并给出盐值与分区的落点校验方法。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》10.1 顺序的粒度与代价</title><link>https://plumephp.com/java-mq-reliable-10-1-ordering-granularity/</link><pubDate>Thu, 29 Oct 2026 07:30:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-10-1-ordering-granularity/</guid><description>同一条消息在单分区里排队，才轮得到顺序。本篇把全局、分区、业务键三种粒度拆开，用 200 条同 key 消息在 in-flight 1/2/5 下各跑三遍，再用暂停 broker 四秒触发超时重试：幂等组 9 次运行全部 0 乱序、0 重复，非幂等组在途 5 时 20 处逆序、5 条重复。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》9.3 最终一致性的度量</title><link>https://plumephp.com/java-mq-reliable-09-3-eventual-consistency-metrics/</link><pubDate>Thu, 29 Oct 2026 07:29:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-09-3-eventual-consistency-metrics/</guid><description>最终一致不是一个形容词，而是一组可以画在面板上的数字。本篇给每条事件带上产生时间戳，在下游落库时计算端到端延迟，本机跑出基线 P50/P95/P99 与最长窗口，再注入 10% 的慢路径看尾延迟怎么变；最后写一个对账任务，故意漏发两条、重发一条，验证它能把条数、金额和重复同时报出来。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》9.2 补偿事务的幂等</title><link>https://plumephp.com/java-mq-reliable-09-2-compensation-idempotence/</link><pubDate>Thu, 29 Oct 2026 07:28:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-09-2-compensation-idempotence/</guid><description>补偿会被重试、重放和并发再次执行；补偿本身不幂等时，一次失败会变成两次超还。本篇在 libraryd 库存场景里分别跑无条件反向更新、WHERE 守卫和补偿令牌三种写法，贴出同一条补偿执行两次的真实差异，并演示补偿服务持续不可用时进入人工队列、恢复后幂等重放的完整路径。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》9.1 Saga：编排与协同</title><link>https://plumephp.com/java-mq-reliable-09-1-saga/</link><pubDate>Thu, 29 Oct 2026 07:27:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-09-1-saga/</guid><description>Saga 把跨服务的长事务拆成一组可补偿的本地动作。本篇用 libraryd 借阅场景实现一个可运行的编排式 Saga：创建借阅、预留库存、冻结额度三步，在第二步和第三步各失败一次，贴出本机真实的补偿轨迹与最终状态，并给出状态机表、崩溃恢复分析与落地清单。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》8.3 Schema Registry 的取舍</title><link>https://plumephp.com/java-mq-reliable-08-3-schema-registry/</link><pubDate>Thu, 29 Oct 2026 07:26:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-08-3-schema-registry/</guid><description>集中式 schema 管理能给你版本查找、兼容性门禁和跨语言契约，代价是多一个服务、多一次依赖和一套客户端耦合。本篇不引入任何第三方 registry 客户端，只用消息头、schema 文件和 CI 脚本，搭一个能跑的最小自管方案，并给出该不该上 registry 的判定表。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》8.2 schema 演进与兼容性</title><link>https://plumephp.com/java-mq-reliable-08-2-schema-evolution/</link><pubDate>Thu, 29 Oct 2026 07:25:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-08-2-schema-evolution/</guid><description>加字段、删字段、改类型、改字段名，四种变更分别能不能兼容？本篇用同一份 JSON payload，让老消费者读新消息、新消费者读旧消息，八个方向逐个跑，贴出 ClassCastException 与 NullPointerException 的原文，并给出双写双读的发布顺序、回滚判据与七条上线前检查清单。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》8.1 领域事件建模</title><link>https://plumephp.com/java-mq-reliable-08-1-domain-event-modeling/</link><pubDate>Thu, 29 Oct 2026 07:24:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-08-1-domain-event-modeling/</guid><description>事件是已经发生的事实，不是请求也不是状态快照。本篇先划清事件体该放什么、不该放什么，再给出 libraryd 六个事件的 record 定义，逐字段说明它为什么存在、缺了会怎样；最后用一次本机实测说明事件 ID 与增量字段如何决定重放是否可重复。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》7.3 事件溯源入门</title><link>https://plumephp.com/java-mq-reliable-07-3-event-sourcing-intro/</link><pubDate>Thu, 29 Oct 2026 07:23:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-07-3-event-sourcing-intro/</guid><description>只存当前状态，你能回答「现在是什么」，回答不了「为什么变成这样」。事件溯源把状态变更本身作为唯一事实来源，状态由重放推导。本篇用纯 JDK 实现最小事件存储，追加 8 个库存事件后从 0 重放得到 stock=9、reserved=12，再用 version=4 的快照加 4 条增量重放，两条路径结果逐字段相等；并实测乐观并发与重复 eventId 两种拒绝。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》7.2 CDC：增量快照与变更捕获</title><link>https://plumephp.com/java-mq-reliable-07-2-cdc/</link><pubDate>Thu, 29 Oct 2026 07:22:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-07-2-cdc/</guid><description>日志挖掘读数据库的变更日志，查询轮询读一张带水位列的表，两者在 op 语义、删除可见性和业务侵入上完全不同。本篇手写轮询版 CDC 实测 c/u/d 三种变更，用同一毫秒的两行证明单列时间水位会漏数据，再用快照前取水位与快照后取水位两种顺序，说明衔接为什么只有前者能得到一致状态；Debezium 仅做架构对照并标注未在本机执行。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》7.1 Outbox 模式</title><link>https://plumephp.com/java-mq-reliable-07-1-outbox/</link><pubDate>Thu, 29 Oct 2026 07:21:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-07-1-outbox/</guid><description>先写库再发消息，会在进程崩溃时留下「有业务行、无事件」的孤儿数据。本篇用同库同事务的 outbox 表消除这个窗口，给出轮询发布器的完整实现，并在本机用嵌入式数据库真实 kill -9：写入 5 笔后崩溃、发送 3 条未标记就崩溃，重启补发后业务行 5、outbox 行 5、Kafka 8 条记录 5 个事件 ID，逐条对上。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》6.3 毒消息隔离与人工干预</title><link>https://plumephp.com/java-mq-reliable-06-3-poison-message/</link><pubDate>Thu, 29 Oct 2026 07:20:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-06-3-poison-message/</guid><description>毒消息不是「处理失败」，而是每次都以同样方式失败、无法自愈的消息。本篇在本机让一条坏消息把整个分区卡住 30 秒：消费位移停在 2，LAG 从 4 涨到 9；再演示转入隔离主题、提交位移、分区恢复消费，并用 libraryd 的退货事件给出人工修复后回灌必须满足的幂等前提。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》6.2 重试主题与退避</title><link>https://plumephp.com/java-mq-reliable-06-2-retry-topic/</link><pubDate>Thu, 29 Oct 2026 07:19:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-06-2-retry-topic/</guid><description>原地重试会占住分区，进程一崩还会丢掉等待中的重试。本篇用三级重试主题把等待外置，实测一条消息从主主题到 DLT 的完整时间轨迹（5 秒、15 秒、45 秒三档退避），量化重试带来的记录放大：100 条业务消息产生 140 条记录，并给出可落地的参数与观测判据。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》6.1 死信队列的设计</title><link>https://plumephp.com/java-mq-reliable-06-1-dlq-design/</link><pubDate>Thu, 29 Oct 2026 07:18:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-06-1-dlq-design/</guid><description>死信队列不是失败消息的垃圾桶，而是一份可回放的失败证据。本篇给出进入死信的判据、必须随消息搬运的元信息清单，并在 Kafka 4.3.0 上跑通完整链路：九条消息中一条重试耗尽进入 DLT，贴出死信头原文，再把修复后的消息回灌原主题，最后给出可验收的判据与反模式清单。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》5.3 消费速率控制与背压</title><link>https://plumephp.com/java-mq-reliable-05-3-consume-backpressure/</link><pubDate>Thu, 29 Oct 2026 07:17:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-05-3-consume-backpressure/</guid><description>下游只有每秒 870 条的能力，消费者硬拉会怎样？实测不限速时 3.7 秒把 3 万条全拉进 JVM，队列峰值 29783，客户端内 p99 滞留 29.7 秒；用 pause/resume 把队列压到 1995，p99 降到 1.9 秒。附一份可运行的背压实现与 AIMD 限速器。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》5.2 积压处置：扩容、跳过与降级</title><link>https://plumephp.com/java-mq-reliable-05-2-backlog-playbook/</link><pubDate>Thu, 29 Oct 2026 07:16:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-05-2-backlog-playbook/</guid><description>积压处置的第一步不是扩容，而是算清楚「追得上还是追不上」。本篇用 9 万条真实积压，分别走加消费者、提高批量和跳过三条路径，记录每秒采样的 LAG 曲线：3 个消费者只快 1.4 倍、批量放大 10 倍只快 13%、跳过 7.2 万条要先等组变空。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》5.1 lag 的三种口径与误读</title><link>https://plumephp.com/java-mq-reliable-05-1-lag-definitions/</link><pubDate>Thu, 29 Oct 2026 07:15:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-05-1-lag-definitions/</guid><description>同一时刻同一分区，kafka-consumer-groups.sh 报 LAG=800，客户端 records-lag-max 显示 900，手算 LEO−position 是 600。三个数都不是 bug，而是三种口径。本篇用一次真实取数把这三种口径拆开，附源码依据与 70 秒空转后指标变 NaN 的实测。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》4.3 扩缩容与优雅停机</title><link>https://plumephp.com/java-mq-reliable-04-3-scale-graceful-shutdown/</link><pubDate>Thu, 29 Oct 2026 07:14:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-04-3-scale-graceful-shutdown/</guid><description>扩容一个消费者会触发整组再平衡，停机的姿势决定了消息是重复、丢失还是要等会话超时。本篇给出一份完整可运行的优雅停止代码，用 1200 条消息实测 SIGTERM 后零重复零丢失；再让一个消费者停 poll 25 秒，贴出 max.poll.interval.ms 踢出的原始 WARN 日志，并数清 1212 次投递里的重复。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》4.2 分配策略与消费者倾斜</title><link>https://plumephp.com/java-mq-reliable-04-2-assignment-skew/</link><pubDate>Thu, 29 Oct 2026 07:13:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-04-2-assignment-skew/</guid><description>7 个分区、2 到 3 个消费者，range、round-robin、sticky、cooperative-sticky 四种策略各跑一遍：谁撤销了全部分区，谁只撤销搬走的那几个，谁多花一轮协议，谁把 8 个分区分成 4-2-2。本篇把分配结果、迁移分区数、再平衡耗时与倾斜成因放进同一组实测数据，并给出观测与选型方法。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》4.1 消费组设计：按业务还是按分区</title><link>https://plumephp.com/java-mq-reliable-04-1-group-design/</link><pubDate>Thu, 29 Oct 2026 07:12:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-04-1-group-design/</guid><description>消费组不是一个进程列表，而是一份职责加一套位移。本篇用 600 条消息、两个快慢不同的消费者和三个订阅同一主题的组，量出「同组能力必须一致」与「多组订阅的复制成本」，再给出按业务域、按处理职责、按分区手工分配三种方案的对照，以及组 ID 命名、空组回收与选择清单。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》3.3 事务的性能与运维代价</title><link>https://plumephp.com/java-mq-reliable-03-3-transaction-cost/</link><pubDate>Thu, 29 Oct 2026 07:11:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-03-3-transaction-cost/</guid><description>事务不是免费的：多一次协调器往返、多一个状态主题、多一段 LSO 阻塞，还要为 abort 的数据付磁盘钱。本篇用 broker 请求日志数出每个事务多发了哪些 RPC，用两组单次运行对比事务与非事务的发送耗时，并给出判断「什么时候不该用事务」的工程判据。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》3.2 事务超时、fencing 与 abort</title><link>https://plumephp.com/java-mq-reliable-03-2-transaction-timeout/</link><pubDate>Thu, 29 Oct 2026 07:10:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-03-2-transaction-timeout/</guid><description>事务不会永远开着：transaction.timeout.ms 到期后由协调器主动中止，客户端下一次提交只会收到一个致命错误。本篇实测超时事务的 abort 时点与数据形态，再用两个同 transactional.id 的生产者复现 fencing，说明僵尸写入为什么会被拒绝。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》3.1 事务生产者与 read_committed</title><link>https://plumephp.com/java-mq-reliable-03-1-transaction-producer/</link><pubDate>Thu, 29 Oct 2026 07:09:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-03-1-transaction-producer/</guid><description>事务生产者把多条消息与消费位移放进一个原子单元。本篇跑通 transactional.id、initTransactions、begin/commit/abort 全流程，用同一份数据分别喂给 read_committed 与 read_uncommitted 消费者，对照提交与中止的可见性，并解释 LSO 为什么会挡住事务之后的消息。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》2.3 恰好一次的两种实现与成本</title><link>https://plumephp.com/java-mq-reliable-02-3-exactly-once-cost/</link><pubDate>Thu, 29 Oct 2026 07:08:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-02-3-exactly-once-cost/</guid><description>Kafka 事务保证的是「多条记录与位移一起提交或一起回滚」，业务恰好一次保证的是「副作用只发生一次」，两者覆盖的范围不同。本篇实测每条一事务、十条一批事务与非事务发送的耗时，再用一个 read_committed 消费者重放已提交记录，展示事务提交后业务仍然重复的完整链路，并给出两种方案的对照表与成立前提清单。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》2.2 幂等消费：唯一键、状态机与去重表</title><link>https://plumephp.com/java-mq-reliable-02-2-idempotent-consume/</link><pubDate>Thu, 29 Oct 2026 07:07:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-02-2-idempotent-consume/</guid><description>唯一约束、去重表、状态机是三种成本不同的幂等实现，选错一种会在并发或重放时失效。本篇先比较三者的写放大、存储与失效边界，再给出一份完整可运行的 IdempotentConsumer：按业务键串行化、PROCESSING/DONE 状态、失败不记账、TTL 惰性清理、容量硬上限，并用 3000 次重复投递和 16 线程同键并发验证它。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》2.1 重复的四种来源</title><link>https://plumephp.com/java-mq-reliable-02-1-duplicate-sources/</link><pubDate>Thu, 29 Oct 2026 07:06:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-02-1-duplicate-sources/</guid><description>重复不是一种故障，而是四种：生产侧重试、消费者再平衡、位移回退、下游重放。本篇用单节点 Kafka 分别构造四类重复，给出每类的原始输出与可识别特征——位移是否相同、eventId 是否相同、是否留下新的生产者序列号，并据此给出一张排查判据表。最后给出处理账本的最小设计，让四类重复在日志里可被区分。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》1.3 消费端：手动提交与位移管理</title><link>https://plumephp.com/java-mq-reliable-01-3-consumer-commit/</link><pubDate>Thu, 29 Oct 2026 07:05:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-01-3-consumer-commit/</guid><description>自动提交提交的是「拉取位置」而不是「处理进度」：一次 close 就把 20 条里没处理的 15 条永久跳过。本机用 40 条消息对照 auto-close、auto-kill 与手动提交三种写法，给出已提交位移、重启后重读范围与源码调用链，并划清提交失败时哪些异常可以重试、哪些必须重新加入消费组。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》1.2 生产端：acks、重试与幂等</title><link>https://plumephp.com/java-mq-reliable-01-2-producer-reliability/</link><pubDate>Thu, 29 Oct 2026 07:04:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-01-2-producer-reliability/</guid><description>acks=all 只是必要条件：还要看 min.insync.replicas 是否被副本数钳制、ISR 当时够不够、以及是否发生不干净选举。本篇用一个 controller 加三个 broker 杀掉两任 leader，对照 acks=1 的 100 条静默丢失与 acks=all 的完整保留，再拆开 retries、delivery.timeout.ms 与幂等生产者的边界。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》1.1 端到端可靠性的责任边界</title><link>https://plumephp.com/java-mq-reliable-01-1-reliability-boundary/</link><pubDate>Thu, 29 Oct 2026 07:03:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-01-1-reliability-boundary/</guid><description>一条消息从 send() 到下游落库要经过生产端、broker、消费端、下游存储四段，每段对「成功」的定义都不同。本篇给出四段责任表与各自的失败模式，并用 8 条消息把一次完整追踪和一次崩溃恢复跑出来，说明「消息不丢」到底停在哪一段，以及三段交接处必须写明的契约。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》目录与学习路径</title><link>https://plumephp.com/java-mq-reliable-toc/</link><pubDate>Thu, 29 Oct 2026 07:02:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-toc/</guid><description>卷二全 50 篇的完整目录：五部分、15 章、45 节，加序、前言与两个附录。每章标注它回答的那一个问题，并给出三条阅读路径——赶时间只看判据的、要落地一条链路的、准备做演练与验收的，另外标明哪些实验可以跳过、哪些必须亲手做，以及每节末尾那条判据该怎么用。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》前言：实验环境与故障注入口径</title><link>https://plumephp.com/java-mq-reliable-preface/</link><pubDate>Thu, 29 Oct 2026 07:01:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-preface/</guid><description>把这一卷的实验底座写清楚：单节点与三节点集群怎么起、客户端工程怎么配，以及最关键的故障注入口径——stop、kill、pause、改配置四种手段各自模拟什么、ISR 何时收缩、本机实测到多少，还有哪些故障本机做不出来、必须标注为未执行并说明它影响哪一条结论。</description></item><item><title>《Java 消息中间件·可靠消息与消费治理》序：可靠性是设计出来的，不是配置出来的</title><link>https://plumephp.com/java-mq-reliable-foreword/</link><pubDate>Thu, 29 Oct 2026 07:00:00 +0800</pubDate><guid>https://plumephp.com/java-mq-reliable-foreword/</guid><description>为什么 acks=all、手动提交、事务这三张配置牌各自只对了一半：把端到端可靠性拆成生产、broker、消费、下游四段，逐段说明每段能保证什么、在哪里漏、要付什么代价，以及本卷用哪些可复现的实验和判据把每一段钉死，最后给出三卷的分工与贯穿项目 libraryd-mq 的可靠性需求。</description></item></channel></rss>