Skip to content
极高进阶

一句话答案

MQ 至少投递一次必有重复,幂等方案:唯一消息 ID+去重表、数据库唯一索引、乐观锁 version、业务状态机。

核心要点

方案:

方案适用
唯一消息ID + Redis/DB去重通用
数据库唯一索引INSERT场景
乐观锁(version)UPDATE场景
状态机有状态流转业务

原则: 消费逻辑本身做幂等,不依赖MQ去重

追问与易错

追问方向:

  • 为什么 MQ 不保证 Exactly-Once?(网络不可靠 + 至少投递一次更简单可靠)
  • 去重表用什么存?有什么问题?(Redis/DB,Redis 有过期风险,DB 有性能问题)
  • 幂等性怎么做单元测试?

易错点:

  • ❌ "让 MQ 保证不重复就行了"——MQ 只保证不丢(At Least Once),重复由消费端处理
  • ❌ "唯一索引就能解决所有重复"——只适合 INSERT,UPDATE 需要乐观锁/状态机

💡 记忆锚点

幂等 = 电梯按钮按多次和按一次效果一样。MQ保证至少投递一次所以必有重复,消费端自己做幂等:INSERT用唯一索引挡重复,UPDATE用乐观锁version防覆盖,有状态流转用状态机(已支付不能再支付)。