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

@@ -140,7 +140,7 @@ public void onFile(FileData msg) { } // 只收 tag=node-01 的消息,
@MqListener(topic = "LN_Topic", group = "g", idempotent = false)
public void onData(FrontData msg) { }
// 批量:攒够 batchSize 条一次给你,参数要用 List
// 批量:攒够 batchSize 条或超时 batchTimeoutMs缺省 60s一次给你,参数要用 List
@MqListener(topic = "LN_Topic", group = "g", batchSize = 50)
public void onBatch(List<FrontData> msgs) { }
@@ -164,7 +164,7 @@ public class MyErrorHandler implements MqConsumeErrorHandler {
> ⚠️ **不配 `errorHandler` = 失败静默丢弃**。未指定 `errorHandler` 时,单条 / 批量 / 重试耗尽的任何消费失败最终都会被 ACK、不落库、不留痕迹ACK 终止是内建行为,与是否落库无关)。关键消费务必配上 `errorHandler` 落库,否则失败即丢、事后无从排查。
>
> ⚠️ **批量有几个坑**:参数必须写带具体元素类型的 `List<FrontData>`(裸 `List` 启动扫描直接抛 `IllegalStateException`没有 idle flush低流量攒不满会一直等进程重启会丢内存里没攒满的那批;整批业务失败只回调 SINGLE 落库、不重投(所以批量务必配 `errorHandler`)。只适合高流量、能接受这些取舍的场景。批量方法同样可以加第二参 `MqContext`(拿到的是该批最后一条的元数据)。
> ⚠️ **批量有几个坑**:参数必须写带具体元素类型的 `List<FrontData>`(裸 `List` 启动扫描直接抛 `IllegalStateException`攒不满时最多等 `batchTimeoutMs`(缺省 60 秒,从本批第一条算起)会强制刷出,正常停机也会把没攒满的批刷出去,但 kill -9 / 断电仍会丢内存里那批(最多一个超时窗口内的量);整批业务失败只回调 SINGLE 落库、不重投(所以批量务必配 `errorHandler`)。批量方法同样可以加第二参 `MqContext`(拿到的是该批最后一条的元数据)。
>
> 另外 `batchSize` 与首参是否 `List` **错配时不报错**:启动时打一条 WARN 日志、仍按首参决定走不走批量(`batchSize=50` 配单个 payload 退化为逐条;`List` 首参配 `batchSize` 缺省按 1 条一批)。见启动日志 `[mq] @MqListener batchSize=...`。
@@ -179,7 +179,7 @@ public class MyErrorHandler implements MqConsumeErrorHandler {
| 去重 `idempotent`(默认开启) | ✅(需 Redis | ✅(需 Redis |
| 失败落库 `RETRY_EXHAUSTED`(需配 `errorHandler`,否则仅 ACK 丢弃) | ✅ | ✅ 落库+ACK |
| 失败落库 `SINGLE` | ⚠️ 单条:落库+重投;批量:失败被吞(两端一致) | ⚠️ 单条:落库+重投;批量:失败被吞(两端一致) |
| 批量 `batchSize` | ⚠️ core 内存攒批driver 逐条喂);无 idle flush低频停滞/重启丢未满批(两端一致) | ⚠️ core 内存攒批driver 逐条喂);无 idle flush低频停滞/重启丢未满批(两端一致) |
| 批量 `batchSize` | ⚠️ core 内存攒批driver 逐条喂);超时/停机强制刷出,仅 kill -9 丢未满批(两端一致) | ⚠️ core 内存攒批driver 逐条喂);超时/停机强制刷出,仅 kill -9 丢未满批(两端一致) |
| 重试 | ✅ PEL reclaim | ✅ 原生重投 |
| 死信队列 | ❌ 只落库 | ⚠️ 原生 `%DLQ%` 通常被耗尽 ACK 旁路InProgress 白跑烧光计数时仍会进) |
| 顺序消息 | ❌ | ❌ 用的 Concurrently |
@@ -262,6 +262,7 @@ core 是中立的,编排逻辑不依赖 Spring 和 Redis可以直接单测
| `group` | 必填 | 消费组名。同一组的多个实例**分摊**消费(一条消息只被组内一个实例消费),不同组**各收一份**全量。消费进度跟着组走:换个组名就是新组,两端都**从最新消息开始收、不回放历史**rocketmq 新组默认最新位点redis-stream 建组用 `$` |
| `concurrency` | 1 | 并发消费线程数,**当前两 driver 均未按此字段兑现**redis 单线程 poll、rocketmq 用原生线程池默认值) |
| `batchSize` | 1 | 攒批大小,大于 1 要用 `List` 参数;与首参是否 `List` 错配时启动打 WARN、仍按首参跑 |
| `batchTimeoutMs` | 60000 | 批量攒批最长等待毫秒数从本批第一条算起到点未满也强制刷出0/负数关闭;仅批量监听器生效 |
| `maxRetry` | 3 | 最大重试次数redis-stream 按 PEL delivery 计数判耗尽 / rocketmq 写入 broker `maxReconsumeTimes`;被去重标记挡回的 InProgress 白跑**两端都计入** |
| `tag` | `*` | 只收打了指定 tag 的消息(发送端三参 `send` 的第二参打 tag。rocketmq 为 broker 服务端过滤、支持原生表达式(如 `A \|\| B`redis-stream 当前不过滤、全收。详见「消费」一节的 tag 小节 |
| `idempotent` | true | 是否去重(默认开启,需 Redis 可达;单个监听器关闭写 `idempotent = false`,全局关闭配 `mq.idempotent.enabled=false` |
@@ -306,8 +307,8 @@ RocketMQ 这边直接复用 rocketmq-spring 原生的 `rocketmq.*` 配置(`nam
**对接异构发送方后,只有第一条消息能消费、后面成片丢失?**
几乎必是去重 key 撞车发送方没填或写死了 keyredis-stream 信封 `key` field / rocketmq 报文头 KEYS 属性所有消息共用一把去重钥匙第一条成功后其余全被判重复静默 ACK让发送方保证 key 逐条唯一Redis Stream 消息结构一节兑现前先在对应监听器上显式 `idempotent = false`
**批量消费收不到 / 停滞 / 丢消息?**
没有 idle flush攒不满 `batchSize` 不触发整批失败会被吞掉不重投低流量把 `batchSize` 调小或改单条消费
**批量消费收不到 / 延迟 / 丢消息?**
攒不满 `batchSize` 时最多等 `batchTimeoutMs`缺省 60 才刷出嫌慢就把它调小整批失败会被吞掉不重投务必配 `errorHandler`kill -9 / 断电会丢内存里没攒满的批正常停机会强制刷出不丢
**消费失败后消息不见了、事后查不到?**
多半是没配 `errorHandler`没配时单条 / 批量 / 重试耗尽的失败一律只 ACK 丢弃不留痕迹关键消费用 `@MqListener(errorHandler = "beanName")` 落库进阶用法」。
@@ -326,7 +327,7 @@ P0放量到生产前想补的
- [x] 失败落库去重批量消费core 已做
- [x] rocketmq driver 补上去重和 `RETRY_EXHAUSTED` 落库 redis-stream 对齐去重 store 已抽成 driver 中立的 `mq-starter-idempotent-redis`
- [ ] 批量消费加 idle flush现在低流量下攒不满会卡着进程重启还会丢内存里没攒满的那批
- [x] 批量消费加 idle flush2026-07-14 落地batchTimeoutMs 超时强刷 + 停机强刷kill -9 仍丢内存未满批
- [ ] 顺序消息
- [ ] 事务消息