接口幂等性

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 接口幂等性一、定义

接口幂等性

一、定义

幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。


在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。


幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。


例如,“setTrue()”函数就是一个幂等函数,无论多次执行,其结果都是一样的.更复杂的操作幂等保证是利用唯一交易号(流水号)实现。


这是来自百度百科的解释,讲人话幂等性就是指接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。


二、使用场景

对于查询的借口来说,可以天然的实现幂等性,因为不管查询多少次都是一样的结果。


而对于增删改的借口来说,我们也需要保证其接口的幂等性。


好比当用户多点击了几次创建商品的操作,这时候前端会重复请求一个新增的接口(要求后台执行一次创建),这时候后端重复创建了多条记录,这就是没有实现接口幂等性所带来的bug,也是我们需要避免的情况。


以下是接口幂等性可以使用的场景:


前端重复提交表单:在填写一些表格时候,用户填写完成提交,很多时候会因网络波动没有及时对用户做出提交成功响应,致使用户认为没有成功提交,然后一直点提交按钮,这时就会发生重复提交表单请求。

用户恶意进行刷单:例如在实现用户投票这种功能时,如果用户针对一个用户进行重复提交投票,这样会导致接口接收到用户重复提交的投票信息,这样会使投票结果与事实严重不符。

接口超时重复提交:很多时候 HTTP 客户端工具都默认开启超时重试的机制,尤其是第三方调用接口时候,为了防止网络波动超时等造成的请求失败,都会添加重试机制,导致一个请求提交多次。

消息进行重复消费:当使用 MQ 消息中间件时候,如果发生消息中间件出现错误未及时提交消费信息,导致发生重复消费。

三、影响

幂等性是为了简化客户端逻辑处理,能放置重复提交等操作,但却增加了服务端的逻辑复杂性和成本,其主要是:


把并行执行的功能改为串行执行,降低了执行效率。

增加了额外控制幂等的业务逻辑,复杂化了业务功能;

所以在使用时候需要考虑是否引入幂等性的必要性,根据实际业务场景具体分析,除了业务上的特殊要求外,一般情况下不需要引入的接口幂等性。


使用幂等性最大的优势在于使接口保证任何幂等性操作,免去因重试等造成系统产生的未知的问题


使用幂等性最大的优势在于使接口保证任何幂等性操作,免去因重试等造成系统产生的未知的问题

四、实现方式


该主键一般来说并不是使用数据库中的自增主键,而是使用分布式ID充当主键,这样才能保证分布式环境下ID的全局唯一性

防重Token令牌:集群环境采用token+redis(redis是单线程的,处理需要排队),单JVM环境采用token+jvm内存,针对客户端连续点击或调用方超时重试等情况


调用接口前向后端申请token,token放入redis(作为key,用户信息作为value)或jvm内存中,并设置有效时间

提交请求需携带token,后台验证是否存在token,以及value是否匹配,存在且匹配则请求成功并删除token,否则则请求失败

执行redis的查找和删除存在并发问题,在并发情况下,执行 Redis 查找数据与删除需要保证原子性,可以通过使用分布式锁或Lua表达式来注销查询和删除操作。

状态机制幂等:状态变更, 更新数据时判断状态


如果状态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论上是不能够变更的

电商订单,订单支付状态 0 待支付,1 支付中,3 支付成功,4 支付失败

update order set status = 1 where status =0 and orderId = “201251487987”

该sql语句利用状态CAS 保证该操作的幂等

比如要进行订单支付,上来先用CAS更新订单状态

返回影响数为 1 代表修改成功,可以支付,继续执行支付业务代码

返回影响数为 0 代表修改失败,该订单已经不是待支付订单了

悲观锁:获取数据时加锁获取


在用户请求操作数据库前对表或行进行上锁,等完成操作后再将锁释放

此时若有第二次请求企图访问数据库则会在尝试获取锁时失败

乐观锁:只是在更新数据时锁表,其他时间不锁表,所以相对于悲观锁,效率更高


提前在对应的数据表中多添加一个字段,充当当前数据的版本标识

每次对该数据库该表的这条数据执行更新时,都会将该版本标识作为一个条件,值为上次待更新数据中的版本标识的值,保证一定更新的是某个版本对应下的信息

重复更新时,在第二次更新的时候版本已经改变,故无法更新成功以实现幂等

分布式锁:通过第三方的系统(redis或zookeeper),在业务系统插入数据或者更新数据,获取分布式锁,然后做操作,之后释放锁


插入数据的例子,如果是分布是系统,构建全局唯一索引比较困难,例如唯一性的字段没法确定,这时候可以引入分布式锁

某个长流程处理过程要求不能并发执行,可以在流程执行之前根据某个标志(用户ID+后缀等)获取分布式锁,其他流程执行时获取锁就会失败,也就是同一时间该流程只能有一个能执行成功,执行完成后,释放分布式锁(分布式锁要第三方系统提供)

缓存队列:将请求放入队列,后续使用异步任务处理队列中的数据,过滤掉重复的消息。 和防止重复消费道理是一样

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
7月前
接口幂等性设计
接口幂等性设计
81 1
|
7月前
接口幂等性注解@RepeatSubmit
接口幂等性注解@RepeatSubmit
243 1
|
7月前
|
NoSQL 关系型数据库 MySQL
接口防刷 && 接口幂等性问题
接口防刷 && 接口幂等性问题
95 0
|
前端开发 NoSQL JavaScript
常见接口和服务幂等性问题及解决方案
常见接口和服务幂等性问题及解决方案
420 0
|
7月前
|
存储 缓存 安全
接口的幂等性
接口的幂等性
76 0
|
1月前
|
设计模式 缓存 前端开发
什么是幂等性?四种接口幂等性方案详解!
本文深入分布式系统中的幂等性问题及其解决方案,涵盖数据库唯一主键、乐观锁、PRG模式和防重Token等方法,关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
什么是幂等性?四种接口幂等性方案详解!
|
2月前
|
数据库
什么是接口幂等性?如何保证接口幂等性?
接口幂等性(Idempotency)是指同样的请求被重复执行多次,产生的结果与执行一次的结果相同。换句话说,接口无论被调用一次还是多次,系统的最终状态保持不变。
205 5
|
2月前
|
存储 缓存 安全
如何保证接口幂等性,幂等性到底是干什么的
本文介绍了幂等性原则及其在程序中的应用。首先定义了幂等性,即无论执行多少次,结果不变的特性,并区分了幂等与非幂等操作。接着详细探讨了实现幂等性的策略,如使用唯一标识符、幂等性标记字段、乐观锁版本控制等。最后,通过Java示例展示了如何实现无状态幂等操作,并强调了幂等性在分布式系统和高并发场景下的重要性。
152 0
|
4月前
|
SQL 索引
分布式之接口幂等性
分布式之接口幂等性
50 2
|
6月前
|
数据库 API 网络架构
浅谈应用接口的幂等性
【6月更文挑战第2天】本文介绍幂等性是计算和网络通信中的重要概念,确保同一操作执行多次不会改变结果。在数据库操作中,查询、删除(同一数据)和特定更新是幂等的,而插入和累加更新不是。幂等性和安全性(如GET、HEAD等方法)确保多次请求无副作用,对涉及金钱的操作尤为重要。
81 0