hongawen f0dc785998 fix(mq-starter): 落实 opus review 反馈(含 1 个 Critical 静默丢消息)
- [Critical] dispatcher errorHandler 抛异常时仍保证 markFail + 抛原始异常(safeOnError 隔离):
  否则去重标记停在 processing,reclaim 重投被去重挡掉并 ACK → 静默丢消息
- [Important] 重试耗尽回调携带完整 payload(reclaim 解码 body,不再传 null)
- [Important] reclaim 默认 idle 5s→30s,避免多实例误 reclaim in-flight 消息;注释 at-least-once 语义
- [Important] idempotent=true 但无 MqIdempotentStore bean 时 start() 告警
- core 引入 slf4j-api(provided);批量失败 / errorHandler 失败均记日志
- errorHandler bean 未找到时抛带 topic/group 的清晰错误
- 文档化已知限制(批量无 idle flush、去重 fail→reopen 非原子)
- 全仓 29 测试绿(含连真实 redis 的 IT)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 20:48:53 +08:00

mq-starter — 统一 MQ 抽象层("MQ 界的 JDBC"

一个独立、全平台通用的 starter。业务配一行 mq.type 选底层(rocketmq | redis-stream 只面向 starter 接口编程,不关心用哪个 MQ、不管理生产者消费者换 MQ = 改配置,业务代码一行不动。

  • 坐标 groupIdcom.njcn,版本 1.0.0-SNAPSHOTPhase 2 阶段本地 mvn install
  • JDK 1.8 / Spring Boot 2.3.12.RELEASE / META-INF/spring.factories 自动装配
  • 零业务依赖:不依赖 message-api 等任何业务模块

业务视角(对外契约)

mq:
  type: redis-stream      # 或 rocketmq
// 发
@Resource MqTemplate mq;
mq.send("LN_Topic", payload);
mq.send("File_Topic", nodeId, payload);   // 带路由 key

// 收(业务方法打注解,零 MQ 概念)
@MqListener(topic = "LN_Topic", group = "ln_consumer")
public void onFrontData(FrontData msg) { /* 纯业务 */ }

模块结构

模块 职责
mq-starter-core 门面 MqTemplate + @MqListener 注解扫描 + 中立信封 MqMessage + driver SPI + 生命周期
mq-starter-rocketmq rocket driver基于官方 rocketmq-spring 编程式注册)
mq-starter-redis-stream redis driver复用 redis-stream-springboot-starter 低层件,零改动 Phase 1
mq-spring-boot-starter 聚合 jar业务方只引这一个坐标

装配机制

@ConditionalOnProperty("mq.type") 静态二选一:两套 driver 各只在对应值下装配, 同一上下文只存在一个 MqDriver bean。

关联设计

  • 设计稿:cn-data-platform/docs/superpowers/specs/2026-06-25-mq-starter-design.md
  • 能力清单与轻量版范围:cn-data-platform/docs/2026-06-25-mq-starter能力清单与轻量版范围.html
  • 实现计划(轻量版 Phase 2cn-data-platform/docs/superpowers/plans/2026-06-25-mq-starter-轻量版-phase2.md
Description
No description provided
Readme 226 KiB
Languages
Java 100%