美文网首页
如何保证接口的幂等性

如何保证接口的幂等性

作者: 乙腾 | 来源:发表于2021-03-15 16:09 被阅读0次

什么是幂等性

HTTP/1.1中对幂等性的定义是:一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外)。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同。

幂等性和防重

防重大多数情况下可以等同于幂等性,都是为了防止多次请求同一个资源造成多次调用多次状态改变。

幂等性场景

用户多次点击按钮
用户页面回退再次提交
微服务互相调用,由于网络问题,导致请求失败。feign 触发重试机制
什么时候需要幂等
除了天然幂等的操作(不被唯一标识限制的操作),而业务逻辑有需要防重,就需要保持其的幂等。

天然幂等性

比如在数据库中,以某一个唯一标识进行查询,新增,删除都是天然幂等的,也就是被唯一标识限制的操作都是幂等的,

幂等常见解决方案

1.token

工作原理:

服务端为需要保持幂等的操作提供token,操作提交的时候在请求中携带token给到后端,后端将请求带来的token和服务端存储的token进行比较,一致则允许其操作资源。

风险

何时删除token?

无论在业务完成前操作token,还是在业务完成后操作token,都是有对应的缺点的,先删除可能导致, 业务因为某些原因没有执行,重试时携带的是之前token,由于防重设计导致,请求不能执行。后删除可能导致,业务处理成功,但是服务闪断,出现超时,没有删除token,别人继续重试,导致业务被执行两遍。
采用token的核心目的是保证幂等性,后删除token的风险解决起来难度很高,而先删除token的所带来的风险解决起来则相对而言是比较容易的。
优化先删除token
先删除token的思路是如果业务调用失败,就重新获取token再次请求。
但是此时先删除token依旧有着风险:
在高并发的场景下,判断入参token和后端存储的token相等的操作没有保证原子性,就像锁保护共享资源一样是有可能重复执行的,从而损失幂等性。
这个问题也是很好解决的,只要保证判断这一步的原子性就可以了。
解决方案:
redis执行lua脚本

//  redis+lua脚本 原子验证令牌防止重复提交攻击
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
String orderToken = "现在的令牌";
//  return 0 失败  1 成功
Long result = stringRedisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class),Arrays.asList("要验证的KEY"), orderToken);

根据result判断是否可以继续进行业务逻辑。

2.锁

悲观锁和乐观锁

悲观锁和乐观锁其实都是一种控制并发保证共享资源的原子性的一种思想,而不是仅仅局限于数据库上。
悲观锁
在修改数据之前对要修改的数据进行加锁操作,排除己身外其他请求获取共享资源的机会。
具体实现:
sql:for update
java:锁
乐观锁
对比悲观锁,他的不同体现在,其是在操作数据的时候再对数据的原子性进行检测,如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。乐观锁相比于悲观锁大大提高了程序的TPS。
具体实现:
对数据增加版本控制。

分布式锁

分布式锁和锁一样,其实就是并行边串行,也可以保证幂等性。

3.唯一约束

数据库的唯一约束
redis set:很多数据需要处理,只能被处理一次,比如我们可以计算数据的MD5将其放入redis的set,每次处理数据,先看这个MD5是否已经存在,存在就不处理。

4.防重表

使用订单号orderNo做为去重表的唯一索引, 把唯一索引插入去重表, 再进行业务操作,且他们在同一个事中。这个保证了重复请求时,因为去重表有唯一约束,导致请求失败,避免了幂等问题。这里要注意的是,去重表和业务表应该在同一库中,这样就保证了在同一个事务,即使业务操作失败了,也会把去重表的数据回滚。这个很好的保证了数据一致性。

5.全局请求唯一id

调用接口时,生成一个唯一id,redis将数据保存到集合中(去重),存在即处理过。

相关文章

  • 接口的幂等性的N种考虑

    分布式服务接口的幂等性如何设计 什么是幂等性 一个分布式系统中的某个接口,要保证幂等性,该如何保证?这个事儿其实是...

  • 如何保证接口的幂等性

    什么是幂等性 HTTP/1.1中对幂等性的定义是:一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时...

  • 如何保证接口的幂等性?

    今天我们来聊聊关于接口的幂等性问题。 什么是幂等性 所谓幂等,就是任意多次执行所产生的影响均与一次执行的影响相同。...

  • 什么是接口的幂等性,如何实现接口幂等性?一文搞定

    每天一个知识点 什么是接口的幂等性,如何实现接口幂等性? (一)幂等性概念 幂等性原本是数学上的概念,用在接口上就...

  • 保证接口幂等性

    幂等性概念在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是...

  • 保证接口幂等性

    说到幂等性,应该很多人都知道这个词,顾名思义,就是无论操作多少次,产生的结果都是相等的。尤其是交易中,在开发过程中...

  • 高并发下,如何保证接口的幂等性?

    高并发下,如何保证接口的幂等性? 幂等性就是同一个操作执行多次,产生的效果一样。如 http 的 get 请求,数...

  • 问题整理

    怎样保证接口幂等性 @transational 有没有遇到失效的场景

  • Redis如何保证接口的幂等性?

    有个小伙伴在最近的一次业务升级中,遇到这样一个问题,我们设计了新的账户体系,需要在用户将应用升级之后将原来账户的数...

  • 冥等性

    编程中的幂等性(二):高并发的系统如何保证幂等性 - 阿官 - CSDN博客

网友评论

      本文标题:如何保证接口的幂等性

      本文链接:https://www.haomeiwen.com/subject/aobkcltx.html