docs: 去重默认开启口径落文档 + 异构发送方对接契约 + tag 用法教学

README:idempotent 默认 true 全文对齐(快速开始加 spring.redis、能力表、注解属性表、
troubleshooting 加「只有第一条能消费」条目);新增「Redis Stream 消息结构」一节
(五字段信封、enc=plain/gzip、key 逐条唯一契约、rocketmq 端 KEYS 属性补注);
新增 tag 小节(broker 过滤 vs redis-stream 全收)。
CLAUDE.md:装配链路第 2 条改为「默认调用 store、Redis 不可达在消费期暴露」口径。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 13:04:08 +01:00
parent 94d5de5182
commit ec5b22b392
2 changed files with 64 additions and 10 deletions

View File

@@ -46,7 +46,7 @@ mq-spring-boot-starter 聚合 jar业务方只引这一个恒含 idemp
各模块 `META-INF/spring.factories` 注册 AutoConfiguration。装配开关是**唯一的** `mq.type`
1. **driver 二选一**`RedisStreamMqDriverAutoConfiguration` / `RocketMqDriverAutoConfiguration` 都用 `@ConditionalOnProperty(name="mq.type", havingValue=...)``mq.type` 条件装配,各自产出一个 `MqDriver` bean。没配 `mq.type` 则两个都不装,`MqTemplate`/`@MqListener` 全部不生效。
2. **去重 store 不按 mq.type 门控**`MqIdempotentRedisAutoConfiguration`idempotent-redis 模块)只按 Redis 在场门控(`@ConditionalOnClass/OnBean(StringRedisTemplate)` + `@AutoConfigureAfter(RedisAutoConfiguration)`),这是 rocketmq 部署也能用上去重的关键。注意 classpath 有 lettuce 时 Spring Boot 会用 localhost 默认值自动造 `StringRedisTemplate`,所以该条件几乎恒真——真正的启动安全网**懒连接 + core 仅在 `idempotent=true` 时才调用 store**(该装配与 store 构造都刻意不 PING Redis与下述 fail-fast 探测相反)。逃生开关 `mq.idempotent.enabled=false`
2. **去重 store 不按 mq.type 门控**`MqIdempotentRedisAutoConfiguration`idempotent-redis 模块)只按 Redis 在场门控(`@ConditionalOnClass/OnBean(StringRedisTemplate)` + `@AutoConfigureAfter(RedisAutoConfiguration)`),这是 rocketmq 部署也能用上去重的关键。注意 classpath 有 lettuce 时 Spring Boot 会用 localhost 默认值自动造 `StringRedisTemplate`,所以该条件几乎恒真——真正的启动安全网只剩**懒连接**(该装配与 store 构造都刻意不 PING Redis与下述 fail-fast 探测相反)——`@MqListener``idempotent` 自 2026-07-14 起**默认 `true`**,消费链默认就会调用 storeRedis 不可达在消费期(而非启动期)以连接异常暴露。逃生开关 `mq.idempotent.enabled=false`(关掉后去重不生效、启动仅打 WARN
3. **core 依赖 driver**`MqCoreAutoConfiguration``MqTemplate``MqListenerRegistry` 都是 `@ConditionalOnBean(MqDriver.class)` —— 有 driver 才有门面。driver 与 idempotent-redis 的 AutoConfiguration 都用 `@AutoConfigureBefore(MqCoreAutoConfiguration.class)` 保证自己先装。
4. **注解扫描**`MqListenerAnnotationBeanPostProcessor`(一个 `BeanPostProcessor`)扫描所有 bean 的方法,把 `@MqListener` 方法收集成 `MqListenerEndpoint` 列表。
5. **启动订阅**`MqListenerRegistry` 实现 `SmartLifecycle``phase = Integer.MAX_VALUE - 100`,最后启动),在 `start()` 里为每个 endpoint 组装 `MqConsumeDispatcher`,包成 `MqSubscription` 交给 `driver.subscribe()`