接口幂等方案

news/2024/10/18 5:40:14/

文章目录

  • 概要
  • 方案
      • 乐观锁
      • 数据库唯一索引
      • 令牌token
          • token通过另一个接口从服务端获取
          • 客户端自身生成token
  • 总结

概要

所谓接口幂等性,就是一次和多次请求某一个资源对于资源本身应该具有同样的影响。接口幂等的应用很广,小到防止表单重复提交,大到分布式系统高可用下的重试策略引起的多次请求。

对接口的请求无外乎增删改查,首先查肯定无需考虑,在没有增删操作的前提下查询肯定是幂等的。其次对于删除也无需考虑,删一次和删多次效果一样。那么需要考虑的就是增加和修改了。

方案

乐观锁

了解乐观锁的同学知道它本质就是版本控制,所以该方案只适合修改(更新)这种场景

对于修改,有一个前提就是资源已经存在了,那么用户想修改该资源就表示用户已经查询到资源了。
大概原理就是用户查询得到资源版本号version,在请求修改接口的时候将其携带上,用于修改操作的控制。
以MySQL为例如下:

update user set name=‘bob’,version=2+1 where id=1 and version=2

这样后续version=2的请求就不会生效。
步骤:

  1. 客户端通过查询接口获取资源版本号;
  2. 客户端请求修改接口,并携带资源版本号;
  3. 服务端收到请求,按照版本号更新数据;
  4. 更新数据条数大于零则成功,否则更新失败,此时返回失败提示或默认成功都可以视业务需求而定。

优点:

  • 简单,只需加一个version字段就可以实现

缺点:

  • 有很大的局限性,只适合修改这种场景,并且要明确每个版本只允许修改一次是正常业务,不然A,B用户都持有version=2,A修改后,B修改不生效是bug还是不是呢?要厘清边界

PS:这里只是以MySQL为例,MySQL只是一个资源载体,你也可以把它放到Redis(原子性用lua脚本保证即可)。

数据库唯一索引

利用唯一索引的唯一性来实现接口幂等,该方案只适合增加(插入)这种场景

场景:插入的数据中含有唯一字段。举一个不太恰当的例子,一个订单只允许对应一条费用记录,这个时候订单id就可以作为费用记录插入时的唯一字段。

步骤:

  1. 客户端提交数据,携带唯一字段(这个唯一字段哪里来呢?)
  2. 服务端收到请求,执行数据插入;
  3. 数据库插入成功则成功,否则需判断是否是唯一索引冲突。

优点:

  • 简单,只需要建立合适的唯一索引即可

缺点:

  • 有很大的局限性,只适合插入场景,并且是简单的插入场景

令牌token

上面两种方案都是在资源本身上进行操作,跳出资源本身,想象空间就很大了。令牌token就是脱离资源本身来实现接口幂等的方案,见下图:
在这里插入图片描述
这里聊一下上一节提到的唯一字段(token)哪里来呢?

  1. 通过另一个接口从服务端获取,经典场景就是防止表单重复提交;
  2. 客户端自身生成,经典场景如微服务架构下订单生成后再通过库存模块接口扣商品库存数量,此时订单模块就是客户端,其本身的订单号即可作为token来实现幂等。

根据token来源延伸出一下两种方案。
ps:token是唯一的

token通过另一个接口从服务端获取

幂等接口1
时序图如上图,逻辑很清晰,没啥可说的,不过这里要唠叨一下:

检测token存在与删除token这两个操作要保证原子性,否则多个请求并发过来,都查到token存在,再都删除,都执行业务逻辑,那接口就丧失了幂等性。

基于上述原因,考虑到常用的存储中间件,那token存储方式最好选用Redis,而不是MySQL,MongoDB之类的。Redis可以用lua脚本保证查询与删除命令的原子执行,而MySQL,MongoDB之类的就不好搞了,单点应用加锁也不是不行,多点呢?上分布式锁?那直接用Redis不香吗?

客户端自身生成token

幂等接口2
流程图如上,逻辑很清晰,没啥可说的,不过这里也要唠叨一下:

存储token可以选Redis,也可以是MySQL,MongoDB之类的:

  • 选Redis检测token存在用set NX即可;
  • 选MySQL,MongoDB之类的,则在token字段上建立唯一索引,借用唯一索引特性来检测,此时捕获唯一索引冲突错误即可。

ps:这里可以思考下,token存储是否要删除呢?多久之后删除比较好,可以根据自身业务看是否需要,需要的话用Redis set NX EX非常方便。

总结

本文讲述了几种实现接口幂等的方案,可以根据自身业务做出最好的选择,一般来说没有任何一种幂等方案可以适用于所有场景,但一令牌token的两种模式足以应付常见的场景了。


http://www.ppmy.cn/news/157610.html

相关文章

前端042_图表展现_自适应

自适应 当缩小窗口时,饼图和柱状图不会自动自适应,会被遮挡住。因为 ECharts 本身并不是自适应的,当你父级容器的宽度发生变化的时候需要手动调用它的 .resize() 方法。 其中 vue-element-admin项目中已经实现了自适应效果,只要将对应代码拷贝引用即可。将 vue-element-adm…

罗技鼠标键盘没法使用,可以尝试安装此驱动

罗技鼠标键盘如果安装了新驱动之后打不开,没法使用,可以尝试安装此驱动,亲试可用 链接:https://pan.baidu.com/s/11cVMH4IwR4h-Ca_QJLpp7g 提取码:mils 复制这段内容后打开百度网盘手机App,操作更方便哦

罗技鼠标驱动G HUB导致触摸板无法使用

因为需要调节鼠标的亮度所以下载了罗技的鼠标驱动,但是在使用过程中发现,触摸板无法使用。 处理步骤如下: 1.卸载罗技G HUB 驱动软件。 2.在设备管理器中,禁用触摸板设备。 3.重新启动即可。 无鼠标下快捷键: 1.SHift…

罗技驱动调节灵敏度方法介绍

罗技驱动怎么调dpi?罗技驱动能适应各个用户的需要,给不同的用户带来相同的舒服的体验感,但每个用户的需要不一样,因此就需要通过调节dpi来满足用户的需求。 罗技驱动怎么调dpi? 1、首先用户需要打开官网的罗技驱动程序…

罗技mx master无法优联连接的解决

默认1通道是USB连接,如果匹配过蓝牙的话通道的信号被占用了,需要下载软件匹配,您可以根据软件提示进行匹配的呢。 优联软件下载:https://support.logi.com/hc/articles/360025297913 (如果打不开,可以科学…

罗技鼠标m590 连接器无法工作

买了M590,手感不错,一开始可以连接两台设备。但是后来我重置了蓝牙,调换了两台设备的连接方法,,就发现蓝牙可以,连接器不行。 尝试一 我比较奇怪,按道理一般连接器要比蓝牙方便,但这…

罗技鼠标驱动安装一直初始化和正在安装问题详解

1、首先去罗技官网下载鼠标和操作系统对应驱动程序(此处省略)。 2、安装一直初始化问题(up是w11系统) 在【设置】-【时间和语言】-【语言&区域】-【管理语言设置】-【管理】-【更改系统区域设置】选项卡下选中【Beta版:使用…

模拟器罗技x56开发使用

罗技Logic x56 飞行器模拟控制器快速上手 输入系统获取按键Unity 2019版本&#xff0c;其他版本应该没有太大变化快速上手 KeyCode枚举 Input 类&#xff0c;InputManager设置窗口x56驱动安装好 Unity自动获取设备信息非常好用 for(int i0;i<(KeyCode)i1;i) {var key Inpu…