每个工程师都应该了解的:聊聊幂等

简介: 每个工程师都应该了解的:聊聊幂等

现在这个时代大家可能最关心的就是钱了,那么有没有想过你银行转账给你没有一次是转多的,要么失败,要么成功,为什么不能失误一下多转一笔呢?醒醒吧年轻人,别做梦了,做银行的能那么傻x吗?


今天我们就来谈一谈为什么银行转账不能多给我转一笔?关乎到钱的问题,小伙伴们打起精神!!!


要想要理解上述的疑惑,不得不提的一个概念就是幂等性,至于什么是幂等性,如何通过代码实现幂等性,下面将会详细讲述。

什么是幂等性          

所谓幂等性通俗的将就是一次请求和多次请求同一个资源产生相同的副作用。用数学语言表达就是f(x)=f(f(x))。

维基百科的幂等性定义如下:

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

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

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

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

为什么需要幂等性      

在系统高并发的环境下,很有可能因为网络,阻塞等等问题导致客户端或者调用方并不能及时的收到服务端的反馈甚至是调用超时的问题。总之,就是请求方调用了你的服务,但是没有收到任何的信息,完全懵逼的状态。比如订单的问题,可能会遇到如下的几个问题:

1. 创建订单时,第一次调用服务超时,再次调用是否产生两笔订单?

2. 订单创建成功去减库存时,第一次减库存超时,是否会多扣一次?

3. 订单支付时,服务端扣钱成功,但是接口反馈超时,此时再次调用支付,是否会多扣一笔呢?

作为消费者,前两种能接受,第三种情况就MMP了,哈哈哈!!!这种情况一般有如下两种解决方式:

1. 服务方提供一个查询操作是否成功的api,第一次超时之后,调用方调用查询接口,如果查到了就走成功的流程,失败了就走失败的流程。

2. 另一种就是服务方需要使用幂等的方式保证一次和多次的请求结果一致。

 

HTTP的幂等性      

GET:只是获取资源,对资源本身没有任何副作用,天然的幂等性。

HEAD:本质上和GET一样,获取头信息,主要是探活的作用,具有幂等性。

OPTIONS:获取当前URL所支持的方法,因此也是具有幂等性的。

DELETE:用于删除资源,有副作用,但是它应该满足幂等性,比如根据id删除某一个资源,调用方可以调用N次而不用担心引起的错误(根据业务需求而变)。

PUT:用于更新资源,有副作用,但是它应该满足幂等性,比如根据id更新数据,调用多次和N次的作用是相同的(根据业务需求而变)。

POST:用于添加资源,多次提交很可能产生副作用,比如订单提交,多次提交很可能产生多笔订单。

幂等性的实现方式        

对于客户端交互的接口,可以在前端拦截一部分,例如防止表单重复提交,按钮置灰,隐藏,不可点击等方式。但是前端进行拦截器显然是针对普通用户,懂点技术的都可以模拟请求调用接口,所以后端幂等性很重要。

后端的幂等性如何实现?将会从以下几个方面介绍。

1. 数据库去重表

在往数据库中插入数据的时候,利用数据库唯一索引特性,保证数据唯一。比如订单的流水号,也可以是多个字段的组合。

实现比较简单,读者可以自己实现看看,这里不再提供demo了。

2. 状态机

很多业务中多有多个状态,比如订单的状态有提交、待支付、已支付、取消、退款等等状态。后端可以根据不同的状态去保证幂等性,比如在退款的时候,一定要保证这笔订单是已支付的状态。

业务中常常出现,读者可以自己实现看看,不再提供demo。

3. TOKEN机制

针对客户端连续点击或者调用方的超时重试等情况,例如提交订单,此种操作就可以用Token的机制实现防止重复提交。

TOKEN机制如何实现?简单的说就是调用方在调用接口的时候先向后端请求一个全局ID(TOKEN),请求的时候携带这个全局ID一起请求,后端需要对这个全局ID校验来保证幂等操作,流程如下图:

主要的流程步骤如下:

1. 客户端先发送获取token的请求,服务端会生成一个全局唯一的ID保存在redis中,同时把这个ID返回给客户端。

2. 客户端调用业务请求的时候必须携带这个token,一般放在请求头上。

3. 服务端会校验这个Token,如果校验成功,则执行业务。

4. 如果校验失败,则表示重复操作,直接返回指定的结果给客户端。

通过以上的流程分析,唯一的重点就是这个全局唯一ID如何生成,在分布式服务中往往都会有一个生成全局ID的服务来保证ID的唯一性,但是工程量和实现难度比较大,UUID的数据量相对有些大,此处陈某选择的是雪花算法生成全局唯一ID

相关文章
|
安全 NoSQL API
互联网并发与安全系列教程(08) - API接口幂等设计与实现
互联网并发与安全系列教程(08) - API接口幂等设计与实现
75 0
|
消息中间件 存储 架构师
架构师一口气说透分布式数据一致性问题
架构师一口气说透分布式数据一致性问题
|
6月前
|
SQL 存储 NoSQL
系统设计——幂等性与解决方案
系统设计——幂等性与解决方案
167 0
系统设计——幂等性与解决方案
【分布式事务】分布式事务 最大努力通知
【1月更文挑战第15天】【分布式事务】分布式事务 最大努力通知
|
消息中间件 存储 前端开发
该如何理解接口的幂等性?这里总结的很到位
随着互联网的发展,Web API 已成为现代应用程序的重要组成部分,它允许不同的应用程序之间进行通信和数据交换。 那么今天就来讲下关于 Web API 中接口幂等性的一些技术内容,希望对大家有所帮助。
|
存储 Dubbo 关系型数据库
国王小组:开发交易所搭建|如何处理分布式事务一致性
对于分布式事务,大家一般会想到以前的JTA标准,2PC两段式提交。我记得当年在Dubbo群里面,基本每周都会有人询问Dubbo啥时候支撑分布式事务。实际上根据分布式系统中CAP原则,当P(分区容忍)发生的时候,强行追求C(一致性),会导致(A)可用性、吞吐量下降,此时我们一般用最终一致性来保证我们系统的AP能力。当然不是说放弃C,而是在一般情况下CAP都能保证,在发生分区的情况下,我们可以通过最终一致性来保证数据一致。
|
消息中间件 中间件 Java
分布式事务解决方案-最大努力通知|学习笔记
快速学习分布式事务解决方案-最大努力通知
116 0
分布式事务解决方案-最大努力通知|学习笔记
|
Java 数据库 索引
稳定性三十六计-幂等设计
为什么要幂等 世界上最遥远的距离是我终于鼓起勇气,对着马路对面的你大喊:“你愿意娶我吗?”我看到你面带灿烂的笑容,正回答的时候……一辆大卡车驶过,你的回答我没有听见。 因各种不可抗因素产生的没有收到响应,一个简单有效的方法就是重试。被重试的接口必须是幂等的。 幂等性是分布式系统设计中的一个重要概念,对超时处理、系统恢复等具有重要意义。
稳定性三十六计-幂等设计
|
NoSQL 关系型数据库 MySQL