如何在PubSub订阅间迁移?需满足无消息丢失、无重复处理要求
PubSub 订阅A到B的无丢失无重复迁移方案
核心实现方案(无消费中断+无重复)
1. 先实现消费幂等逻辑
在消费代码里加一层幂等校验:
- 用PubSub消息自带的
messageId(全局唯一),或者业务自定义的唯一标识作为判断依据 - 处理消息前先查存储(数据库、Redis等),确认该消息是否已经处理过
- 未处理则执行业务逻辑,处理完标记该消息为已处理;已处理则直接确认消息,跳过业务执行
2. 创建订阅B
直接创建绑定目标主题的订阅B,此时B会同步接收主题的新消息,同时拉取所有A未确认的历史消息。
3. 启动双消费模式
保持消费A的旧代码继续运行,同时启动消费B的新代码。双消费期间,两条消费流都会拉取消息,但通过幂等逻辑保证同一消息只会被实际处理一次。
4. 等待A的积压消息清零
监控订阅A的未确认消息数,直到数值降到0。这一步确保A中所有历史消息都已被处理(不管是A还是B处理的,幂等逻辑避免了重复)。
5. 停旧代码并收尾
- 停止消费A的旧代码
- 后续仅运行消费B的新代码
- 确认B稳定后,可删除订阅A(可选)
方案优势
- 无消息丢失:B创建后覆盖所有新消息,A的积压消息也会被处理完毕
- 无重复处理:幂等逻辑从业务层规避了重复执行问题
- 无消费中断:双消费阶段旧代码不停,业务不受影响
备选方案(适合无法快速实现幂等的场景)
如果业务暂时加不了幂等逻辑,可以用快照迁移法,但会有短暂消费中断:
- 先停止消费A的旧代码
- 给订阅A创建快照(记录当前A的已确认消息状态)
- 用这个快照创建订阅B,此时B会继承A的确认状态,仅包含A未处理的消息
- 启动消费B的新代码
- 确认B运行正常后,删除订阅A
这个方案的好处是完全不会有重复消息,但缺点是停止旧代码到启动新代码的这段时间,主题新消息会在B中积压,适合对消费中断容忍度较高的场景。
内容的提问来源于stack exchange,提问作者dmab
相关产品推荐
相关产品推荐

