一、 状态机
前提条件:
- 在消费者业务表中存在状态字段,并在消费消息后是变更状态
- 状态流转是单向不可逆的。例如:
status :[1 → 2 → 3 → 4...]
实现方式:
基于数据库乐观锁CAS方式。例如: update table set status = 2... where status = 1
二、 数据库唯一约束
前提条件:
- 消息消费者在业务表中需要存储
上游业务唯一id
实现方式:
在消息这业务表中加入上游业务唯一id并设置为唯一约束。
三、消息去重表
前提条件:
- 消息消费者必须存在数据库持久化操作
- 保证消费者对其业务表数据增删改和去重表入库在同一个
Connection的同一个Transaction中
实现方式:
- 每个库都需要建立一个消息去重表
- 对
上游业务唯一id设置唯一约束 - 设置消费时间字段,根据业务场景设置记录有效时间
5d、7d、10d,使用定时任务定时清除过期消费记录 - 在消息消费前,根据
上游业务唯一id查询消息去重表,存在则直接ACK;在消费者操作完自身业务后,同时保存消息信息到消息去重表
优化方式:
可以加入redis缓存层,在查询时查询redis是否存在该上游唯一id,在消息消费者消息同时存入redis中,并设置有效期
优点:
相对于方法一、方法二可以使用注解 + AOP从业务中解耦,无侵入、统一处理的方案









