暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

如何保证接口幂等性?

源1024 2021-05-24
411

什么是幂等


在我们编程中常见幂等

  • select查询天然幂等

  • delete删除也是幂等,删除同一个多次效果一样

  • update直接更新某个值的,幂等

  • update更新累加操作的,非幂等

  • insert非幂等操作,每次新增一条

产生原因

由于重复点击或者网络重发 :

  • 点击提交按钮两次;

  • 点击刷新按钮;

  • 使用浏览器后退按钮重复之前的操作,导致重复提交表单;

  • 使用浏览器历史记录重复提交表单;

  • 浏览器重复的HTTP请;

  • nginx重发等情况;

  • 分布式RPC的try重发等;

什么情况需要处理幂等

对于数据只能处理有且仅有一次的业务场景,例如:支付订单,扣费的操作。对于同一个订单号,只能扣费一次。不论是经过接口调用,还是通过mq消费消息,已经扣费了,如果有相同的请求过来,必须保证最终扣费结果一致。
一般导致重复提交的场景:
前端用户重复提交:客户端卡顿,用户习惯多次点击页面按钮导致同一时间多次提交。
调用接口超时重试:调用接口是如果遇到网络抖动,导致请求发出了,返回接受超时,这时调用者并不知道执行结果,进行了重试。
MQ消费重复:消费端消费消息超时,消息重新入队,MQ将消息发送到其他消费端。


如何实现接口幂等

  • token

对于用户的重复提交,可以使用token机制避免。在后端生成全局唯一的token,存放在redis,前端请求带上token,后端接口接受到携带的token,判断redis是否存在,存在则删除并进行业务处理,不存在则表示token已处理过,是重复请求,不做处理。


  • 唯一标识

对于存在唯一标识的业务场景,在建表时需要建立唯一索引避免重复提交带来的脏数据。例如:用户名唯一,对用用户名做唯一索引约束。订单支付表,对订单id做唯一索引约束。


  • 乐观锁

通过判断更新时的数据是否跟当前预期更新的数据一致,即CAS原理,不一致则根据业务提示失败,一致才更新。例如:使用更新时间判断数据是否被修改,判断是否跟查询时拿到的更新时间一致。update table1 set name='123' where id=1 and update_time='2021-05-20 00:00:00';


  • 状态机

在设计单据相关的业务,或者是任务相关的业务,肯定会涉及到状态机(状态变更图),就是业务单据上面有个状态,状态在不同的情况下会发生变更,一般情况下存在有限状态机

如果状态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论上是不能够变更的,这样的话,保证了有限状态机的幂等。

注意:订单等单据类业务,存在很长的状态流转,一定要深刻理解状态机,对业务系统设计能力提高有很大帮助。


  • 分布式锁

通过第三方的系统(redis或zookeeper),在业务系统插入数据或者更新数据,获取分布式锁,然后做操作,之后释放锁。



文章转载自源1024,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论