docs: 批量 idle flush 落地后口径同步(README/CLAUDE.md)

批量语义从"无 idle flush、低频停滞、重启丢批"改为"超时(缺省 60s)/停机
强制刷出,仅 kill -9 丢未满批";注解属性表补 batchTimeoutMs 行,TODO 勾选。
全景手册(docs/,gitignored)已同步修改,不在本 commit。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 15:07:21 +01:00
parent 244d4d3854
commit b0e0422c10
2 changed files with 9 additions and 7 deletions

View File

@@ -63,7 +63,7 @@ mq-spring-boot-starter 聚合 jar业务方只引这一个恒含 idemp
- **去重的两类跳过**决定 driver 能否 ACK`success` → 正常返回让 driver ACK 挡掉重复;仍 `processing`(并发中或消费者崩溃残留标记)→ 抛 `MqMessageInProgressException` 让 driver **不要 ACK**、保留消息待 `processing` 标记过期后重投。搞错就是**静默丢消息**。
- **单条消费失败**:先落库(**仅当配了 `errorHandler`**`safeOnError` 对 null handler 静默跳过、不落库)+ `store.markFail()`(把去重标记从 processing 复位),再抛原异常交 driver 重投。跳过 `markFail` 会让标记卡在 processingreclaim 重投时被去重挡掉并 ACK → 静默丢消息。
- **批量消费**无 idle flush攒够 `batchSize` 才 flush低流量下未满批会停滞进程重启丢内存里没入库的那批与 legacy 行为一致,适合高流量流)。批量失败因消息已逐条 ACK 无法精确重投整批,故落库(同样只在配了 `errorHandler` 时)+ 吞掉不抛。
- **批量消费**满批 / 超时(`batchTimeoutMs` 缺省 60s从本批首条算起registry 全局单线程 `mq-batch-flush` 每 1s 扫)/ 停机stop 时 `forceFlush`)三路径刷出,统一走 `doFlush``flushLock` 串行化业务批量方法任一时刻至多一个调用kill -9 仍丢内存未刷批(上界 = 一个超时窗口)。批量失败因消息已逐条 ACK 无法精确重投整批,故落库(同样只在配了 `errorHandler` 时)+ 吞掉不抛。
driver 侧对 `MqMessageInProgressException` 的对应处理:`RedisStreamMqDriver.java` 捕获后不 `acknowledge()`(留 PEL 待 reclaim`RocketMqDriver.java` 在通用 `catch(Exception)` **之前**单独捕获并返回 `RECONSUME_LATER`绝不进耗尽落库分支——catch 顺序不能动,它是 `Exception` 子类)。边缘(**两端共性**2026-07-14 复核InProgress 白跑会烧重试计数——rocketmq 每次 `RECONSUME_LATER` 使 `reconsumeTimes` +1烧光进原生 `%DLQ%`进死信、非丢消息redis-stream 每次 reclaimxClaim使 PEL delivery +1`deliveryCount > maxRetry` 时**不再 dispatch** 直接判耗尽(配了 `errorHandler` 落库,没配则静默丢弃——业务可能一次都没重跑)。缓解同构:`mq.idempotent.processing-ttl` 小于 maxRetry 轮重投累计时长rocketmq 默认 ~100s / redis-stream 为 `maxRetry × reclaim-min-idle` 默认 90s
@@ -82,6 +82,7 @@ driver 只需实现 `MqDriver``send` / `subscribe` / `stop`)。其余是可
- 参数只能是 `(payload)``(payload, MqContext)`,第二参必须是 `MqContext`
- `batchSize > 1` 时首参要用 `List<T>`,且**必须声明具体元素类型**`List<FrontData>`,不能裸 `List`)—— driver 仍按 `T` 逐条反序列化dispatcher 负责攒批。
- `batchSize` 与首参是否 `List` 的**错配只打 WARN、不阻断启动**2026-07-14 决策,刻意软校验):走不走批量始终只由首参决定——`batchSize>1` 配单 payload 按单条跑,`List` 首参配 `batchSize<=1` 按 1 条一批跑。
- `batchTimeoutMs` 仅批量监听器生效;`batchSize<=1` 且显式配了非缺省值时同样只打 WARN 软校验、不阻断(恰好显式写 60000 检测不出,已知可接受)。
## 启动期 fail-fast 校验(近期新增,改动时留意)