架构设计-技术收藏实战收藏-解决篇实战案例-优化系列

请求频繁重试,后端接口如何幂等?

2020-02-20  本文已影响0人  DoubleFooker

接口幂等

什么情况需要处理幂等

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

如何实现接口幂等

例如简单的查询接口,查询商品详情,无论查询多少次,也不会对查询的结果有影响。

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

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

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

对于业务数据存在多种状态的情况,这些状态的流转往往有不可逆的情况,在更新状态时需要判断当前状态是否符合期望,否则不更新或抛出异常。例如:update order set status='payed' where id=1 and status='paying';

上一篇下一篇

猜你喜欢

热点阅读