一、什么是幂等性?
在数学里,幂等有两种主要的定义。
- 在某二元运算下,幂等元素是指被自己重复运算的结果等于它自己的元素。例如,乘法下唯一两个幂等实数为0和1。
- 某一元运算为幂等的时,其作用在任一元素两次后会和其作用一次的结果相同。例如,高斯符号便是幂等的。
在计算机领域,幂等性指多次操作对系统产生的影响与一次操作相同。举个例子,假设要删除用户A,无论请求多少次,操作结果都是删除用户A,而不会删除用户B。
在RESTful风格的接口中,幂等性表现在HTTP请求方法中:
-
GET
幂等,即要获取用户A的信息,多次请求系统,返回的皆是用户A的信息。是返回结果相同而不是返回内容相同。 -
POST
非幂等,用户注册,多次调用接口,会新增多条用户数据。 -
PUT
幂等,put请求与post的区别是,post请求倾向于新增数据,而put请求倾向于更新数据,如果数据不存在则会根据客户端提供的完整数据资源创建数据。所以对于put操作来说,多次调用接口产生的结果是一样的,即客户端提交的数据都会被更新到系统中。 -
PATCH
非幂等,patch是对put的补充。顾名思义patch即补丁,用于更新子资源的部分内容,同样地,如果要更新的数据不存在则允许创建数据。可以发现patch和put非常相似,那为什么put是幂等的,而patch非幂等呢?因为patch允许根据客户端提供的某个值动态计算更新内容,例如每次调用某个参数+1,则多次调用会产生不同结果。
二、接口中的幂等性
无论是微服务中各个子系统相互之间的调用,还是客户端对服务端的调用,都存在网络延迟等问题,会导致重复请求接口,这时候接口就需要支持幂等性,来防止出现问题。
最经典的一个例子就是订单支付操作,假如因为网络问题等因素导致用户重复提交,这时候不可能对用户重复扣款,否则客服电话就要被打爆了。
那么服务端接口对于幂等性应该如何支持呢?有如下两个思路:
1. 逻辑判断处理
支付时对订单状态进行判断,如果该订单已支付,则不应该再次进行扣款操作。
2. 请求带ticket
异步请求获取ticket,此ticket是唯一并且一次性的,保存在页面中,每次发起支付请求都带上ticket,后端检查ticket,若支付成功则删除ticket,这样就算重复提交也不会导致重复扣款。