[TOC]
# 幂等性
* 所谓幂等性通俗的将就是一次请求和多次请求同一个资源产生相同的副作用。
数学语言表达就是`f(x)=f(f(x))`。
* 维基百科的幂等性定义如下:
~~~
幂等(idempotent、idempotence)是一个数学与计算机学概念,常见于抽象代数中。 在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“setTrue()”函数就是一个幂等函数,无论多次执行,其结果都是一样的,更复杂的操作幂等保证是利用唯一交易号(流水号)实现.
~~~
在编程中,一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数或幂等方法是指可以使用相同参数重复执行,并能获得相同结果的函数 / 方法。这些函数 / 方法不会影响系统状态,因此不用担心重复执行会对系统造成改变。例如:
1. 前端重复提交选中的数据,后台也只会产生对应这个数据的一个反应结果。
2. 用户发起一笔付款请求,就应该只扣用户一次钱,即使遇到网络重发或系统 bug 重发请求,也应该之扣一次钱。
3. 发送验证短息也应该只发一次,同样的验证短信不应该发送多次。
4. 创建业务订单,一个业务请求只能创建一个业务订单,创建多个就会出大问题。
这些等等很多的业务逻辑都需要幂等的特性来支持。
简单来理解就是,幂等就是一个操作,这个操作不管执行多少次,产生的效果和返回的结果都是一样的。比如说有一个 getOne () 函数,无论执行这个函数多少次,它返回的都是 1,这时就可以说它是一个幂等函数。
# 为什么需要幂等性
* 在系统高并发的环境下,很有可能因为网络,阻塞等等问题导致客户端或者调用方并不能及时的收到服务端的反馈甚至是调用超时的问题。总之,就是请求方调用了你的服务,但是没有收到任何的信息,完全懵逼的状态。比如订单的问题,可能会遇到如下的几个问题:
1. 创建订单时,第一次调用服务超时,再次调用是否产生两笔订单?
2. 订单创建成功去减库存时,第一次减库存超时,是否会多扣一次?
3. 订单支付时,服务端扣钱成功,但是接口反馈超时,此时再次调用支付,是否会多扣一笔呢?
* 作为消费者,前两种能接受,第三种情况就 MMP 了,哈哈哈!!!这种情况一般有如下两种解决方式
1. 服务方提供一个查询操作是否成功的 api,第一次超时之后,调用方调用查询接口,如果查到了就走成功的流程,失败了就走失败的流程。
2. 另一种就是服务方需要使用幂等的方式保证一次和多次的请求结果一致。
# 参考
[接口幂等性如何实现?](http://blog.itpub.net/69969697/viewspace-2683852/)
[如何做到接口的幂等性](https://cloud.tencent.com/developer/article/1526642)
[幂等性如何实现?深入了解一波!!!](https://mp.weixin.qq.com/s?__biz=MzI0ODYzMzIwOA==&mid=2247483974&idx=1&sn=1b71a961636a08aba0b973240df5697b&chksm=e99c8051deeb0947c99f23cdcc2bffacbcb6c4334900bde8c4b627e327213daf11acfffa4703&scene=126&sessionid=1585200996&key=bd873186532b9f4effc489fedbc274400872c0b6a0f4a1eb1e1700cca311c7588c1f2661a73f5321d7143316f249b15e849c1f6b0fe55a85f9268878a171afbc975e667a5e71c592b8528b50e7f1ce72&ascene=1&uin=MTA3MjI0MTk2&devicetype=Windows+10&version=62080079&lang=zh_CN&exportkey=ATKxWBRhz%2BdeVp89aixV7gg%3D&pass_ticket=26t9iuszGw1evGgO2rFoWR%2BnItByEBiAoFQcBTZ4NG4%3D)
- 修仙之路
- 基础原理篇
- JS和Node.js事件环机制剖析
- 一图理解原型链
- 手写篇
- 基础手写
- 手写实现 Promise A+ 类库
- 手写 CommonJS
- 手写 Express 框架
- 手写 React Router 4.0
- 手写虚拟 DOM 和 DOM-Diff
- 手写 Webpack 实现
- 手写一个 MVVM 类库
- 手写一个 Vue-cli 脚手架
- 手写 JWT 类库
- 手写 Mobx 类库
- 手写前端性能和错误监控框架
- 手写 Vue 路由
- 手写 Vuex 实现
- 手写 redux 状态容器
- 手写 throttle 和 debounce
- Node 高级
- Mongodb
- 安全测试篇
- CSRF原理实现
- XSS原理实现
- 九种跨域方法全解析
- 编写单元测试
- 爬虫篇
- 使用puppeteer破解滑动验证码
- 工程篇
- 使用AST语法树手工转译ES6代码
- 编写自己的webpack插件
- 实战篇
- webpack4.0 实战
- Canvas+Websocket 实现弹幕
- canvas 动效
- SVG 动效
- CSS3 实现 Apple Watch 中的呼吸灯效果
- CSS3 实现动态气泡屏保效果
- 算法篇
- 基础知识
- 服务器端
- 分布式架构中的幂等性
- TCP/UDP
- Docker
- V8
- 动画篇
- 贝塞尔曲线
- requestAnimationFrame
- 框架篇
- 随记