怎么理解接口幂等?

幂等实际是一个数学上的概念,在数学上如果函数满足 f(x) = f(f(x)),那么我们称函数f具备幂等性。举个栗子,假设f(x) =|x|,即函数f表示取x的绝对值,那么f(x) = f(f(x))也成立,即f(x) =||x| |。说完了幂等的原始概念,我们再来看下在编程领域,幂等指的又是什么,我们先来看下百度百科的解释。

在编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“setTrue()”函数就是一个幂等函数,无论多次执行,其结果都是一样的.更复杂的操作幂等保证是利用唯一交易号(流水号)实现。

那么我们怎么理解接口幂等呢?举个简单的例子,我们经常用的秒杀服务,在秒杀结束前,我们会疯狂的点击收集屏幕的下单按钮,但是对于秒杀而言,一个用户只能买一件,所以无论你点了多少次,要么没有秒杀到,要么秒杀到,库存只会减1,不会因为你请求了多少,或者系统因为网络重试了多少次,而改变系统的资源情况,多次操作的结果都是一致的,这种情况我们就称系统具备幂等性。

为什么要进行接口幂等设计?

如果我们不对接口进行幂等设计会导致什么问题呢?可以想象一下如果我们在京东上面下单买书,但是扣了两次钱,会有什么结果?再比如,你在银行汇钱的时候,本来要汇10000块,但是因为网络抖动原因,进行了重试,导致汇了30000块,你是不是得炸锅了。
从上面的例子我们可以知道,如果我们不做幂等设计,在一些情况下很可能会出现与我们业务期望不一样的情况,甚至会发生资损的情况,造成客户财产损失,逐渐丧失对于平台的信心,最终导致客户流失。因此我们必须要重视服务幂等问题,确保不出现上述的业务异常情况。

有哪些常见的幂等设计方案?

1、数据库唯一索引

拿用户注册这个场景来说,为了防止连续点击造成的用户信息重复的问题,我们可以在数据库中通过设置用户名、电话号码等字段的唯一性索引的方式来实现幂等,即便是出现了连续点击进行用户创建,但是在数据库层面是不会对重复数据进行入库保存的,从而达到用户服务注册接口实现幂等的目的,但是如果全靠数据库来保证的话,数据库的压力会比较大,因为入库的时候数据库要判断是否唯一,在数据量大的时候非常耗性能。

alter table `user` add UNIQUE KEY `un_user_phone` (`phone`);

2、使用Redis

上面说到唯一键会导致数据库性能下降,那么有更好的解决方案吗?如下业务,订单服务生成订单消息后发送订单消息到MQ中,库存服务根据订单信息来扣减自己的库存。但是由于网络原因,MQ迟迟未收到库存服务的消费成功消息,因此又对库存服务进行了消息投递,因而产生了两个相同订单code的订单,而此时库存服务实际第一次已经消费成功。那么库存服务如何保证幂等呢?我们可以借助于Redis来实现幂等,首先我们通过以业务code未唯一key进行redis设置,这里的业务code就是订单号,保证全局唯一,使用setNx命令。如果可以设置成功,说明是第一次设置,那么可以继续后续的业务流程,进行库存扣减。如果设置不成功,则表明此时Redis已经有对应的订单code了,本次操作属于无效请求,直接返回,不继续后续的业务流程处理。

3、先查询再进行数据操作

在进行数据插入的时候,我们可以先去查询数据是否存在,如果不存在则进行插入操作,如果已存在那么就不再进行后续操作。

这里需要注意的是幂等和防重的区别,幂等实际是包含防重的。为什么这么说呢?防重实际上指的是防止多次请求重复执行,导致系统业务异常。而幂等强调的是即使执行了业务,多次执行和一次执行的效果应该是一致的。说起来好像有点拗口,可以这么理解,重复请求是人为操作的,所以要过滤掉重复的,如秒杀。但是幂等说明的是在微服务内部,由于存在服务间的分布式调用,如果第一次调用未收到响应,会进行第二次调用来进行重试,那么此时系统需要保证两次调用达到的业务效果是一致的。因此幂等实际包含防重操作的。

PS:
大家还知道哪些其他的幂等设计方案?在你们的项目中平台是怎么设计接口幂等的?欢迎大家在评论区留言讨论哦。


大家好,我是慕枫,感谢各位小伙伴点赞、收藏和评论,文章持续更新,我们下期再见!

真正的大师永远怀着一颗学徒的心

微信搜索:慕枫技术笔记,优质文章持续更新,我们有学习打卡的群可以拉你进,一起努力冲击大厂,另外有很多学习以及面试的材料提供给大家。

架构师之路系列:接口幂等性是个什么东东?如何实现接口幂等设计?相关推荐

  1. 开始Go开发之旅-Golang架构师之路系列实战

    2019独角兽企业重金招聘Python工程师标准>>> 作者: gomaster.me(冯琪超) 系列:Golang架构师之路 巧妇难做无米之炊,golang sdk就是gopher ...

  2. 通往架构师之路系列之Java设计模式(二)工厂方法模式

    前言 参考:虫洞栈 工厂模式又称工厂方法模式,是一种创建型设计模式,其在父类中提供一个创建对象的方法,允许子类 决定实例化对象的类型. 这种设计模式也是 Java 开发中最常见的一种模式,它的主要意图 ...

  3. Android从程序员到架构师之路3

    本文学习自高焕堂老师的Android从程序员到架构师之路系列教学视频 40 - 认识线程(Thread)模式a 1. 线程(Thread)概念 所谓线程(Thread) 是指一串连续的执行动作,以达成 ...

  4. 架构师之路17年精选80篇

    [架构必备] <互联网架构如何实现"高并发">4W+ <TCP接入层的负载均衡.高可用.扩展性架构设计>2.2W+ <配置中心架构设计演进>1. ...

  5. python爬虫架构师之路_一位资深 架构师大牛给予Java技术提升的学习路线建议

    一位资深 架构师大牛给予Java技术提升的学习路线建议 对于工作多年的程序员而言,日后的职业发展无非是继续专精技术.转型管理和晋升架构师三种选择. 架构师在一家公司有多重要.优秀架构师需要具备怎样的素 ...

  6. 1对多业务,数据库水平切分架构一次搞定 | 架构师之路

    1对多业务,数据库水平切分架构一次搞定 | 架构师之路 原创 2017-07-10 58沈剑 架构师之路 架构师之路 架构师之路 微信号 road5858 功能介绍 架构师之路,坚持撰写接地气的架构文 ...

  7. Java集合总结(架构师之路 )

    JAVA架构师之路 本系列文章均是博主原创,意在记录学习上的知识,同时一起分享学习心得. 第一章 第一节 Java集合总结(架构师之路 ) 第二节 Java多线程(架构师之路 ) 前言 本章内容是博主 ...

  8. 架构师之路-写的不错

    架构师之路 转:http://www.uml.org.cn/zjjs/200903273.asp 1.引言 机算机科学是一门应用科学,它的知识体系是典型的倒三角结构,所用的基础知识并不多,只是随着应用 ...

  9. Java高级架构师之路核心知识整理

    小编整理出一篇Java高级架构师之路的核心知识,同时也是面试时面试官必问的知识点,篇章也是包括了很多知识点,其中包括了有基础知识.Java集合.JVM.多线程并发.spring原理.微服务.Netty ...

最新文章

  1. GPUtil是一个Python模块,使用nvidia-smi从NVIDA GPU获取GPU状态
  2. [转]MFC下关于“建立空文档失败”问题的分析
  3. How web servers work?
  4. FLV封装格式分析器
  5. C语言试题五十六之计算并输出给定整数n的所有因子(不包括1与自身)之和。规定n的值不大于1000。
  6. java 文件缓冲区_Java开发笔记(八十六)通过缓冲区读写文件
  7. nginx php分离,nginx-php配置动静分离
  8. 华为面试改革,我们该怎么跟进?
  9. 关于Toad的Cannot load OCI DLL问题
  10. JavaScript-解构赋值
  11. 无法打开文件ws32_2.lib ws2_32.lib
  12. Git 2.29.2 64位安装包
  13. 电子商务计算机考研学校排名,电子商务考研院校排名
  14. SQL Server笔记心得(持续更新)
  15. 费曼学习法为什么会如此有魅力
  16. python 开启子进程的两种方式
  17. 响应式分布式区别_边缘计算的七种定义,边缘计算与云计算、雾计算的区别
  18. 信息用短信服务器发送什么意思,已用短信息服务发送是什么意思
  19. 模拟ic流片经验分享
  20. 基于图像的三维重建研究

热门文章

  1. 沈阳师范大学大二上数据结构第一章绪论(选择+单选+填空))
  2. 网络原理考点之BSC协议
  3. nginx rewrite if指令剖析
  4. QQ软件已被破坏或部分文件丢失,就是木马病毒引起的
  5. 微信小程序怎么判断是从哪个页面跳转进来的!!
  6. ShaderToy入门教程(2) - 光照和相机
  7. AST实战|免安装一键还原ob混淆详细使用教程
  8. 计算机代数的应用,计算机代数及其应用-陶庆生(1991).pdf
  9. c语言中箭头的作用,为什么C中的箭头(-)运算符存在?
  10. 读吕林根之《解析几何》