去重表与消费幂等

用数据库唯一约束或去重表记录已处理的消息标识,重复投递时直接跳过;与业务更新放在同一事务中,才能保证“处理+记录”原子。

思路

思路
BEGIN;
INSERT INTO msg_dedupe(msg_id, created_at) VALUES (?, NOW());
-- 唯一键冲突则回滚并视为已处理
UPDATE account SET balance = balance - 100 WHERE id = ?;
COMMIT;
去重记录需要设置合理的保留窗口并定期归档,长窗口会带来存储与索引成本。

易错点

  • 去重表与业务更新不在同一事务,仍会出现重复处理
  • 去重窗口过短,延迟重投递的消息未被拦截

数据来源与参考

  • Chris Richardson《Microservices Patterns》
  • Apache Kafka 官方文档:消息投递语义
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌