幂等的概念

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

复制代码

在编程中,一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变。例如,“getUsername()和setTrue()”函数就是一个幂等函数。

用通俗的话讲:就是针对一个操作,不管做多少次,产生效果或返回的结果都是一样的

举几个例子:

比如前端对同一表单数据的重复提交,后台应该只会产生一个结果

比如我们发起一笔付款请求,应该只扣用户账户一次钱,当遇到网络重发或系统bug重发,也应该只扣一次钱

比如发送消息,也应该只发一次,同样的短信如果多次发给用户,用户会崩溃

比如创建业务订单,一次业务请求只能创建一个,不能出现创建多个订单 复制代码

还有很多诸如此类的,这些逻辑都需要幂等的特性来支持。

实现幂等性的技术方案

查询操作

查询一次和查询多次,在数据不变的情况下,查询结果是一样的,select是天然的幂等操作。

删除操作

删除操作也是幂等的,删除一次和多次删除都是把数据删除。(注意可能返回结果不一样,删除的数据不存在,返回0,删除的数据多条,返回结果多个)。

唯一索引,防止新增脏数据

拿资金账户和用户账户来说,每个用户只能有一个资金账户,怎么防止给用户创建资金账户多个,那么给资金账户表中的用户ID加唯一索引,在新增的时候只有一个能请求成功,剩下都会抛出唯一索引重复异常。比如 org.springframework.dao.DuplicateKeyException,这时候再查询一次就可以了,数据存在,返回结果

token机制,防止页面重复提交
要求:页面的数据只能被点击提交一次发生原因:由于重复点击或者网络重发,或者nginx重发等情况会导致数据被重复提交解决办法:

集群环境:采用token加redis

单JVM环境:采用token加redis或token加jvm内存 处理流程:

数据提交前要向服务的申请token,token放到redis或jvm内存,token有效时间

提交后后台校验token,同时删除token,生成新的token返回 token特点:要申请,一次有效性,可以限流

注意:redis要用删除操作来判断token,删除成功代表token校验通过,如果用select+delete来校验token,
存在并发问题,不建议使用

悲观锁

获取数据的时候加锁获取

注意:id字段一定是主键或者唯一索引,不然是锁表,会出事的。悲观锁使用时一般伴随事务一起使用,数据锁定时间可能会很长,根据实际情况选用

乐观锁

乐观锁只是在更新数据那一刻锁表,其他时间不锁表,所以相对于悲观锁,效率更高。

乐观锁的实现方式多种多样可以通过version或者其他状态条件:

1.通过版本号实现

2.通过条件限制

update table_xxx
setavai_amount
=
avai_amount
-#
subAmount
# where avai_amount-#subAmount# >= 0

要求: avai_amount-subAmount>=0这个情景适合不用版本号,只更新是做数据安全校验,适合库存模型,扣份额和回滚份额,性能更高。

注意:乐观锁的更新操作,最好用主键或者唯一索引来更新,这样是行锁,否则更新时会锁表,上面两个sql改成下面的两个更好。

分布式锁

还是拿插入数据的例子,如果是分布是系统,构建全局唯一索引比较困难,例如唯一性的字段没法确定,这时候可以引入分布式锁,通过第三方的系统(redis或zookeeper),在业务系统插入数据或者更新数据,获取分布式锁,然后做操作,之后释放锁,其实就是为了控制多线程并发的操作,也是分布式系统中经常用到的解决思路。

select + insert

并发不高的后台系统,或者一些任务JOB,为了支持幂等,支持重复执行,简单的处理方法是,先查询下一些关键数据,判断是否已经执行过,在进行业务处理,就可以了。

注意:核心高并发流程不要用这种方法。

状态机幂等

在设计单据相关的业务,或者是任务相关的业务,肯定会涉及到状态机(状态变更图),就是业务单据上面有个状态,状态在不同的情况下会发生变更,一般情况下存在有限状态机,这时候,如果状态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论上是不能够变更的,这样的话,保证了有限状态机的幂等。

注意:订单等单据类业务,存在很长的状态流转,一定要深刻理解状态机,对业务系统设计能力提高有很大帮助。

对外提供接口的api如何保证幂等
如银联提供的付款接口:需要接入商户提交付款请求时附带:source来源,seq序列号

source+seq在数据库里面做唯一索引,防止多次付款,(并发时,只能处理一个请求)。

重点:

对外提供接口为了支持幂等调用,接口有两个字段必须传,一个是来源source,一个是来源方序列号seq,这个两个字段在提供方系统里面做联合唯一索引,这样当第三方调用时,先在本方系统里面查询一下,是否已经处理过,返回相应处理结果;没有处理过,进行相应处理,返回结果。注意,为了幂等友好,一定要先查询一下,是否处理过该笔业务,不查询直接插入业务系统,会报错,但实际已经处理了。

最后总结:

幂等性应该是合格程序员的一个基因,在设计系统时,是首要考虑的问题,尤其是在像第三方支付平台,银行,互联网金融公司等涉及的网上资金系统,既要高效,数据也要准确,所以不能出现多扣款,多打款等问题,这样会很难处理,并会大大降低用户体验。

·END·

原文发布时间为:2019-1-3
本文作者:x7lovelin
本文来自云栖社区合作伙伴“ 程序猿DD”,了解相关信息可以关注“didispace”微信公众号

来谈下高并发和分布式中的幂等处理 1相关推荐

  1. 我们来谈下高并发和分布式中的幂等处理

    我们先来谈下幂等的概念 抽象概念 幂等(idempotent.idempotence)是一个数学与计算机学概念,常见于抽象代数中. 在编程中,一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行 ...

  2. 来谈下高并发和分布式中的幂等处理

    来源:https://0x9.me/MRqcj 幂等的概念 幂等(idempotent.idempotence)是一个数学与计算机学概念,常见于抽象代数中. 复制代码 在编程中,一个幂等操作的特点是其 ...

  3. 高并发和分布式中的幂等处理

    今日推荐 这 9 个 Java 开源项目 yyds,你知道几个?阿里技术专家推荐的20本书,免费送!K8S 部署 SpringBoot 项目(一篇够用)妙用Java 8中的 Function接口 消灭 ...

  4. java唯一订单号_java web在高并发和分布式下实现订单号生成唯一的解决方案

    方案一: 如果没有并发,订单号只在一个线程内产生,那么由于程序是顺序执行的,不同订单的生成时间戳正常不同,因此用时间戳+随机数(或自增数)就可以区分各个订单.如果存在并发,且订单号是由一个进程中的多个 ...

  5. Linux下高并发socket最大连接数所受的各种限制

    修改最大打开文件数 # ulimit -n 修改最大进程数 # ulimit -u ------------------------------------------------------ Lin ...

  6. linux socket文件数限制,Linux下高并发socket最大连接数所受的限制问题

    Linux下高并发socket最大连接数所受的限制问题1.修改用户进程可打开文件数限制在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时, 最高的并发数量都要受到系统对 ...

  7. Linux进程最大socket数,Linux下高并发socket最大连接数所受的各种限制(详解)

    1.修改用户进程可打开文件数限制 在Linux平台上,无论编写客户端程序还是服务端程序,在进行高并发TCP连接处理时,最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是因为系统为每 ...

  8. LruCache在美团DSP系统中的应用演进(生动诠释了计算机三幻神(缓存,高并发,分布式))

    背景 DSP系统是互联网广告需求方平台,用于承接媒体流量,投放广告.业务特点是并发度高,平均响应低(百毫秒). 为了能够有效提高DSP系统的性能,美团平台引入了一种带有清退机制的缓存结构LruCach ...

  9. 阿里P8架构师谈:高并发网站的监控系统选型、比较、核心监控指标

    在高并发分布式环境下,对于访问量大的业务.接口等,需要及时的监控网站的健康程度,防止网站出现访问缓慢,甚至在特殊情况出现应用服务器雪崩等场景,在高并发场景下网站无法正常访问的情况,这些就会涉及到分布式 ...

最新文章

  1. plotly可视化绘制多子图(subplots)共享坐标轴
  2. Git的使用和提交规范
  3. Git远程操作详解【转】
  4. HPU暑期第五次积分赛 - G-迷宫(BFS+最短路径)
  5. Ant和Junit使用的一些问题
  6. linux源码安装apache2,CentOS7编译安装Apache2
  7. 常见字符编码 java
  8. 机器学习之朴素贝叶斯算法原理
  9. 漏洞10年深藏不露,PHP 项目依赖关系管理工具Composer安全吗?
  10. Canvas 超详细
  11. Latex中文期刊论文模板
  12. 刷ROM必備的clockworkmod recovery
  13. 2022网易校招易计划在线课程
  14. Java实现 LeetCode 134 加油站
  15. docker 进入,退出容器命令
  16. 论return 0的高级写法 bushi​​​​​​​)
  17. 什么是适合中小企业的ERP
  18. Utopia unlimited: reassessing American literary utopias【翻译】
  19. 24位AD和16位DA超高精度PID串级控制器在张力控制中的应用
  20. Java反射——Type接口详解

热门文章

  1. EOS的账户授权和多重签名
  2. unas 下 Aria2 使用体会
  3. 计算机网络复习总结(超详细加思维导图)
  4. 9成企业打算发年终奖,人均到手2.3万元
  5. 欢迎光临寒舍!!!本blog 正在筹建中~~~~~
  6. 注意:雪花算法并不是ID的唯一选择!
  7. 万维网之父正投身的“互联网去中心化”事业,目前仍有这几大难题
  8. Chango的数学Shader世界(八)光盘模拟-各向异性,光栅衍射
  9. 11月11日大师献给各位染成茜色的坂道FANS的礼物—— あかね色に染まる坂是怎么破解的?
  10. discard long time none received connection错误解决