一、什么是幂等性

幂等性:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用

二、分布式系统中哪些地方需要注意幂等性

(1)用户在使用产品时,可能会误操作触发多次,或者长时间无响应触发多次

(2)Kafka消息重复,生产者可能会出现消息发送情况,消费者也可能出现重复消费情况

(3)系统的重试机制,业务可能为了考虑失败的情况,出现多次重试,如Fegin调用、回调方法处理

三、需求

一个用户对于同一个操作发起一次或者多次的请求,请求的结果一致,不会因为多次点击而产生多条数据,接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的

四、实现方案

2.1 通过业务唯一主键约束

Mysql的insert ignore或者on duplicate key update的语句特性保证接口处理业务的一致性

insert ignore:插入数据时,如遇主键、唯一索引冲突,则不会插入数据,且不会报错

on duplicate key update:插入数据时,如遇主键、唯一索引冲突,则通过主键、唯一索引进行更新数据操作

适用场景:数据表中用户只存在唯一数据的业务场景(用户id为主键、联合主键),可通过数据库特性来控制接口幂等性

2.2 通过token防止重复提交

通过采用token+Redis(由于Redis是单线程的,处理须要排队)

(1)数据提交之前需要在后台调用token生产接口,每次请求前都需要调用

(2)后台把唯一token值存在Redis中,返回给调用方

(3)调用方提交请求带上token值,后台进行校验token,

(4)后台通过调用放携带的token值直接执行删除操作

(5)删除成功则进行后续业务处理,不成功处理业务直接响应相关提示

2.3 通过分布式锁实现

通过分布式锁实现,在业务系统插入数据或者更新数据,先获取分布式锁,分布式锁的标识可为(用户id+接口type),同一个用户、同一个接口在规定时间内只能执行一次,获取不到锁的请求可以直接响应或者阻塞等待,可根据业务需求来处理。

分布式锁基于Redis来实现,分布式锁在某个线程占用之后,其他线程就不能获取到对应的锁,获取不到锁的线程可直接重复调用响应结果

2.4 通过对请求参数进行校验

实现原理:请求如出现重复请求,请求参数参数大概率是一致的,或者能根据多个请求参数值来判断是否为重复请求,通过对可判断是否重复请求的参数(可配置)进行hash code运算存于Redis中设置失效时间(可配置),每次请求都根据配置的请求参数计算一次code值,通过code值判断请求是否属于重复请求

该方案是通过自己总结处理,未在网上找到案例,需讨论后执行

五、总结

如业务符合唯一主键约束,优先使用主键约束处理接口幂等性,不满足的业务需求可通过配置验证请求参数、有效时间段来重复接口重复请求。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注