• 1.幂等性定义

    • 1.1 数学定义
    • 1.2 HTTP规范的定义
  • 2. 何种接口提供幂等性
    • 2.1 HTTP支持幂等性的接口
    • 2.2 实际业务
  • 3.分布式系统接口幂等性
  • References

1.幂等性定义

1.1 数学定义

在数学里,幂等有两种主要的定义:

  • 在某二元运算下,幂等元素是指被自己重复运算(或对于函数是为复合)的结果等于它自己的元素。例如,乘法下唯一两个幂等实数为0和1。 即 s *s = s
  • 某一元运算为幂等的时,其作用在任一元素两次后会和其作用一次的结果相同。例如,高斯符号便是幂等的,即f(f(x)) = f(x)。

1.2 HTTP规范的定义

在HTTP/1.1规范中幂等性的定义是:

A request method is considered 'idempotent' if the intended effect onthe server of multiple identical requests with that method is the same as the effect for a single such request. Of the request methods defined by this specification, PUT, DELETE, and safe request methods are idempotent.

HTTP的幂等性指的是一次和多次请求某一个资源应该具有相同的副作用。如通过PUT接口将数据的Status置为1,无论是第一次执行还是多次执行,获取到的结果应该是相同的,即执行完成之后Status =1。

2. 何种接口提供幂等性

2.1 HTTP支持幂等性的接口

在HTTP规范中定义GET,PUT和DELETE方法应该具有幂等性。

  • GET方法

The GET method requests transfer of a current selected representatiofor the target resourceGET is the primary mechanism of information retrieval and the focus of almost all performance optimizations. Hence, when people speak of retrieving some identifiable information via HTTP, they are generally referring to making a GET request.

GET方法是向服务器查询,不会对系统产生副作用,具有幂等性(不代表每次请求都是相同的结果)

  • PUT方法

T he PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.

也就是说PUT方法首先判断系统中是否有相关的记录,如果有记录则更新该记录,如果没有则新增记录。

  • DELETE 方法

The DELETE method requests that the origin server remove the association between the target resource and its current functionality. In effect, this method is similar to the rm command in UNIX: it expresses a deletion operation on the URI mapping of the origin server rather than an expectation that the previously associated information be deleted.

DELETE方法是删除服务器上的相关记录。

2.2 实际业务

现在简化为这样一个系统,用户购买商品的订单系统与支付系统;订单系统负责记录用户的购买记录已经订单的流转状态(orderStatus),支付系统用于付款,提供

boolean pay(int accountid,BigDecimal amount) //用于付款,扣除用户的

接口,订单系统与支付系统通过分布式网络交互。

这种情况下,支付系统已经扣款,但是订单系统因为网络原因,没有获取到确切的结果,因此订单系统需要重试。
由上图可见,支付系统并没有做到接口的幂等性,订单系统第一次调用和第二次调用,用户分别被扣了两次钱,不符合幂等性原则(同一个订单,无论是调用了多少次,用户都只会扣款一次)。
如果需要支持幂等性,付款接口需要修改为以下接口:

boolean pay(int orderId,int accountId,BigDecimal amount)

通过orderId来标定订单的唯一性,付款系统只要检测到订单已经支付过,则第二次调用不会扣款而会直接返回结果:

在不同的业务中不同接口需要有不同的幂等性,特别是在分布式系统中,因为网络原因而未能得到确定的结果,往往需要支持接口幂等性。

3.分布式系统接口幂等性

随着分布式系统及微服务的普及,因为网络原因而导致调用系统未能获取到确切的结果从而导致重试,这就需要被调用系统具有幂等性。
例如上文所阐述的支付系统,针对同一个订单保证支付的幂等性,一旦订单的支付状态确定之后,以后的操作都会返回相同的结果,对用户的扣款也只会有一次。这种接口的幂等性,简化到数据层面的操作:

update userAmount set amount = amount - 'value' ,paystatus = 'paid' where orderId= 'orderid' and paystatus = 'unpay'

其中value是用户要减少的订单,paystatus代表支付状态,paid代表已经支付,unpay代表未支付,orderid是订单号。
在上文中提到的订单系统,订单具有自己的状态(orderStatus),订单状态存在一定的流转。订单首先有提交(0),付款中(1),付款成功(2),付款失败(3),简化之后其流转路径如图:

当orderStatus = 1 时,其前置状态只能是0,也就是说将orderStatus由0->1 是需要幂等性的

update Order set orderStatus = 1 where OrderId = 'orderid' and orderStatus = 0

当orderStatus 处于0,1两种状态时,对订单执行0->1 的状态流转操作应该是具有幂等性的。
这时候需要在执行update操作之前检测orderStatus是否已经=1,如果已经=1则直接返回true即可。

但是如果此时orderStatus = 2,再进行订单状态0->1 时操作就无法成功,但是幂等性是针对同一个请求的,也就是针对同一个requestid保持幂等。

这时候再执行

update Order set orderStatus = 1 where OrderId = 'orderid' and orderStatus = 0

接口会返回失败,系统没有产生修改,如果再发一次,requestid是相同的,对系统同样没有产生修改。

References

幂等
HTTP幂等性概念和应用
What Is Idempotent in REST?
REST之中的幂等指的是什么?
Hypertext Transfer Protocol (HTTP/1.1)

三、如何保证接口的幂等性

接口的幂等性实际上就是接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。有些接口可以天然的实现幂等性,比如查询接口,对于查询来说,你查询一次和两次,对于系统来说,没有任何影响,查出的结果也是一样。

除了查询功能具有天然的幂等性之外,增加、更新、删除都要保证幂等性。那么如何来保证幂等性呢?

3.1保证幂等策略

幂等需要通过唯一的业务单号来保证。也就是说相同的业务单号,认为是同一笔业务。使用这个唯一的业务单号来确保,后面多次的相同的业务单号的处理逻辑和执行效果是一致的。
下面以支付为例,在不考虑并发的情况下,实现幂等很简单:①先查询一下订单是否已经支付过,②如果已经支付过,则返回支付成功;如果没有支付,进行支付流程,修改订单状态为‘已支付’。

3.2防重复提交策略

上述的保证幂等方案是分成两步的,第②步依赖第①步的查询结果,无法保证原子性的。在高并发下就会出现下面的情况:第二次请求在第一次请求第②步订单状态还没有修改为‘已支付状态’的情况下到来。既然得出了这个结论,余下的问题也就变得简单:把查询和变更状态操作加锁,将并行操作改为串行操作。

列举三种改进方式:

1、悲观锁,select for update,整个执行过程中锁定该订单对应的记录。

2、乐观锁,affectrows = db.update(“update payorder set state=’已支付’ where orderid=$orderid and state=’未支付’ “),如果affectrows=1,执行充值,否则返回已处理。

3、定义防重复表,orderid为unique key或者primary key,执行前,先insert,若insert成功则执行充值,否则返回已处理

分布式系统接口幂等性相关推荐

  1. 【案例分析】分布式系统的接口幂等性设计!

    概念 幂等性, Idempotence, 这个词来源自数学领域, 百科 上一元运算的幂等性解释如下:设 f 为一由 {x} 映射至 {x} 的一元运算, 则 f 为幂等的, 当对于所有在 {x} 内的 ...

  2. 分布式系统接口如何保证幂等性

    分布式系统接口如何保证幂等性 转载请注明出处:https://www.cnblogs.com/jajian/p/10926681.html 业务场景 公司有个借贷的项目,具体业务类似于阿里的蚂蚁借呗, ...

  3. 什么是接口幂等性?为什么会产生这个问题?如何保证接口幂等性?

    作者:三分恶 原文链接:https://cnblogs.com/three-fighter/p/14054749.html 博主负责的项目报了一个问题,用户操作回退失效.我们的设计里,操作回退是回到操 ...

  4. 分布式系统面试 - 幂等性设计

    分布式系统面试 - 幂等性设计 面试题 分布式服务接口的幂等性如何设计(比如不能重复扣款)? 面试官心理分析 从这个问题开始,面试官就已经进入了实际的生产问题的面试了. 一个分布式系统中的某个接口,该 ...

  5. 什么是幂等性?四种接口幂等性方案详解

    幂等性在我们的工作中无处不在,无论是支付场景还是下订单等核心场景都会涉及,也是分布式系统最常遇见的问题,除此之外,也是大厂面试的重灾区. 知道了幂等性的重要性,下面我就详细介绍幂等性以及具体的解决方案 ...

  6. Java生鲜电商平台-生鲜电商高并发下的接口幂等性实现与代码讲解

    说明:Java生鲜电商平台-生鲜电商高并发下的接口幂等性实现与代码讲解,实际系统中有很多操作,是不管做多少次,都应该产生一样的效果或返回一样的结果.例如: 前端重复提交选中的数据,应该后台只产生对应这 ...

  7. java中接口幂等性解决方案总结

    一.概念 一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同.幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数.这些函数不会影响系统状态,也不用担心重复执行 ...

  8. JavaWeb - 接口幂等性

    接口调用存在的问题 现如今我们的系统大多拆分为分布式SOA,或者微服务,一套系统中包含了多个子系统服务,而一个子系统服务往往会去调用另一个服务,而服务调用服务无非就是使用RPC通信或者restful, ...

  9. 什么是接口幂等性?为什么会产生接口幂等性问题?如何保证接口幂等性?

    博主负责的项目报了一个问题,用户操作回退失效.我们的设计里,操作回退是回到操作前的状态.经过查看日志发现,用户之前的操作做了两次,也就是说提交操作的接口被调用了两次,导致之用户上一次的状态和这一次的状 ...

  10. oracle 锁表如何解决_「技术分享」高并发下的接口幂等性解决方案

    高并发下的接口幂等性解决方案! 一.背景我们实际系统中有很多操作,是不管做多少次,都应该产生一样的效果或返回一样的结果.例如:前端重复提交选中的数据,应该后台只产生对应这个数据的一个反应结果.我们发起 ...

最新文章

  1. 又一个 Java 面试神器!
  2. 思科虚拟化与视频技术打造协作新体验
  3. SM12表条目冻结说明
  4. hdu-1576(A/B)
  5. python开源库生成式对抗网络_Python:使用Tensorflow开发一维生成对抗网络
  6. RabbitMQ基本概念(三)-Centos7下安装RabbitMQ3.6.1
  7. 做为一名java高级程序员,需要了解哪些岗位?
  8. FreeMarker_模板引擎_代码自动生成器_源码下载
  9. vue中前进刷新、后退缓存用户浏览数据和浏览位置的实践
  10. 手动设置ip 访问内网地址
  11. java基础热门侠客养成_侠客养成手册攻略大全 新手快速上手攻略[多图]
  12. pcie link/lane number negotiation
  13. 用HTML写一首绝句古诗,唐诗七绝绝句经典50首:唐诗七绝悲伤的句子让人心醉
  14. 时光轴一之listView实现时光轴效果
  15. luogu_1378 油滴扩展
  16. SSM知识梳理(整理一半)
  17. [渝粤教育] 西南科技大学 现代数字系统设计 在线考试复习资料2021版
  18. SpringBoot系列:Spring Boot集成定时任务Quartz,java百度云短信发送
  19. 误提交了target目下的文件怎么删除?
  20. Python:数的分解

热门文章

  1. html原生js请求
  2. Android 微信支付
  3. 读《一天搞懂深度学习》ppt的笔记
  4. 如何系统学习SWAT模型—建模方法、实例应用、高级进阶
  5. js读写json文件
  6. 深入了解JavaScript编程语言
  7. 信号与系统2022春季学期:作业内容与参考答案-汇总
  8. 固态硬盘用软件测试温度高,硬盘温度过高的原因,固态硬盘温度过高-
  9. 大数据技术原理与应用学习笔记(八)
  10. Appium下载和配置