幂等性

目的

幂等只要用于网络接口的特性描述,指的是网络接口的调用可以重试,而不会带来副作用

 

分布式系统的调用失败有一种情况是等待返回时超时,对于这种情况,调用方并不知道之前的的请求是否执行成功,被调用方可能执行成功也可能没有执行成功

这时候如果接口是幂等的,调用方就可以继续发起重试请求,来确保请求最终执行成功

如保证同一个的一笔交易能够不多次进行支付,即使同一时间因为误操作进行了多笔交易,我们也能保证用户的金钱不被多扣

如在进行订单交易的时候 存在扣库存的操作,我们要不存在超卖的情况

如在锁座的时候不存在座位不被重复锁定的问题

 

我们如何设计一个幂等方案呢

 

查询

查询接口在数据不变的情况下本来就是幂等的

删除

删除接口一般也是幂等的

新增

可以使用如下的方式

唯一索引:在数据库级别来帮助实现新增的幂等

token方式

更新

无锁编程

乐观锁 也即是获取数据库字段的版本号,通过乐观锁版本控制更新

乐观锁(条件限制)不增加条件限制,比如使用更新前的值比对

MySQL乐观锁与悲观锁应用

 

幂等性应用场景

在App中下订单的时候,点击确认之后,没反应,就又点击了几次,在这种情况下无法保证该接口的幂等的,那么将会出现重复下单的问题

 

在接受消息的时候,消息重复推送,如果处理消息的接口无法保证幂等性,那么重复消费消息产生的影响可能会非常大

 

在关键书的CU的时候,不保证幂等的情况下,会出现数据重复,或者数据重复写的问题

 

 

token 幂等方案

1、客户端token

当调用创建接口时如果遇到了请求超时或服务器内部错误,用户可能会尝试重发请求,这时用户通过clientToken参数避免创建出比预期要多的资源,即保证请求的幂等性。
幂等性基于clientToken,clientToken是一个长度不超过64位的ASCII字符串,通常放在query string里,
http://eip.bj.baidubce.com/v1/instance?clientToken=be31b98c-5e41-4838-9830-9be700de5a20

如果用户使用同一个clientToken值调用创建接口,则服务端会返回相同的请求结果。因此用户在遇到错误进行重试的时候,可以通过提供相同的clientToken值,
来确保只创建一个资源;如果用户提供了一个已经使用过的clientToken,但其他请求参数(包括queryString和requestBody)不同甚至url Path不同,
则会返回IdempotentParameterMismatch的错误代码。
clientToken的有效期为24小时,以服务端最后一次收到该clientToken为准。也就是说,如果客户端不断发送同一个clientToken,那么该clientToken将长期有效。

 

2、服务端token

设计思路:每次操作生成一个唯一性的凭证,也就是token。一个token在操作的每一个阶段只有一次执行权,一旦执行成功则保存执行结果。对重复的请求,返回同一个结果。

业务场景:页面数据只能被点击提交一次

发生原因:由于重复点击或者网络重发,或者nginx重发等情况可能会导致数据被重复提交

解决办法:集群环境采用token+redis;单JVM环境—采用token+redis或者token+JVM内存

处理流程:1.数据提交前向服务申请token,token放入redis或者JVM内存,token设置有效时间;2.提交后台后校验token,同时删除token,生成新token返回

图解

 

需要考虑的点:

 redis使用删除操作来判断token,删除成功代表token校验通过,如果使用select+delete来校验,存在并发问题,不建议使用?

由于提交前申请token可能存在重试,某一次申请由于延迟,在成功操作并删除token后才到达服务器,将会生成新的token,此时还能重新提交

 

 

token特点:需要申请

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值