当前位置:   article > 正文

高并发下如何保证接口的幂等性?_聊聊高并发下如何保证接口的幂等性?

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

一、什么是幂等性

所谓幂等,简单地说,就是对接口的多次调用所产生的结果和调用一次是一致的。

那么我们为什么需要接口具有幂等性呢?设想一下以下情形:

  • 支付接口,重复支付会导致多次扣钱 订单接口,同一个订单可能会多次创建。
  • 在接收消息的时候,消息推送重复。如果处理消息的接口无法保证幂等,那么重复消费消息产生的影响可能会非常大。

二、幂等性的解决方案

(1)唯一索引

使用唯一索引可以避免脏数据的添加,当插入重复数据时数据库会抛异常,保证了数据的唯一性。

(2)乐观锁

这里的乐观锁指的是用乐观锁的原理去实现,为数据字段增加一个version字段,当数据需要更新时,先去数据库里获取此时的version版本号

select version from tablename where xxx
  • 1

更新数据时首先和版本号作对比,如果不相等说明已经有其他的请求去更新数据了,提示更新失败。

update tablename set count=count+1,version=version+1 where version=#{version}
  • 1
(3)悲观锁

乐观锁可以实现的往往用悲观锁也能实现,在获取数据时进行加锁,当同时有多个重复请求时其他请求都无法进行操作

(4)分布式锁

幂等的本质是分布式锁的问题,分布式锁正常可以通过rediszookeeper实现;在分布式环境下,锁定全局唯一资源,使请求串行化,实际表现为互斥锁,防止重复,解决幂等。

目前主要有三种方式实现redis的分布式锁:

  1. setNx 命令
  2. set 命令
  3. Redission 框架

具体流程图如下:

在这里插入图片描述

具体步骤:

  1. 用户通过浏览器发起请求,服务端会收集数据,并且生成订单号 code 作为唯一业务字段。
  2. 使用 redis 的 set 命令,将该订单 code 设置到 redis 中,同时设置超时时间。
  3. 判断是否设置成功,如果设置成功,说明是第一次请求,则进行数据操作。
  4. 如果设置失败,说明是重复请求,则直接返回成功。

需要特别注意的是:分布式锁一定要设置一个合理的过期时间,如果设置过短,无法有效的防止重复请求。如果设置过长,可能会浪费redis的存储空间,需要根据实际业务情况而定。

(5)token机制

token 机制的核心思想是为每一次操作生成一个唯一性的凭证,也就是 token。一个 token 在操作的每一个阶段只有一次执行权,一旦执行成功则保存执行结果。对重复的请求,返回同一个结果。token 机制的应用十分广泛。

该方案跟之前的所有方案都有点不一样,需要两次请求才能完成一次业务操作。

  1. 第一次请求获取token
  2. 第二次请求带着这个token,完成业务操作。

具体流程图如下:

第一步,先获取token。

在这里插入图片描述

第二步,做具体业务操作。

在这里插入图片描述

具体步骤:

  1. 用户访问页面时,浏览器自动发起获取token请求。
  2. 服务端生成token,保存到redis中,然后返回给浏览器。
  3. 用户通过浏览器发起请求时,携带该token。
  4. 在redis中查询该token是否存在,如果不存在,说明是第一次请求,做则后续的数据操作。
  5. 如果存在,说明是重复请求,则直接返回成功。
  6. 在redis中token会在过期时间之后,被自动删除。

以上方案是针对幂等设计的。

如果是防重设计,流程图要改改:

在这里插入图片描述

需要特别注意的是:token必须是全局唯一的。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号