美文网首页
幂等系统设计

幂等系统设计

作者: 定金喜 | 来源:发表于2020-10-12 23:09 被阅读0次

1.系统为什么需要幂等

  • 前端用户的操作问题导致表单重复提交,不做幂等控制会导致创建多个记录,例如用户下单,可能会导致后端创建多个订单
  • 用户操作的频繁,导致后端出现高并发问题,同一个订单可能会出现重复支付等问题
  • 调用第三方接口,但是系统不做幂等控制,可能会出现两个系统数据不一致问题
  • MQ异步消费,不做幂等控制,会出现重复消费问题

2. 解决方案

  1. 接口的流量控制,通过分布式锁来对接口进行流量限制,对于一些可能存在幂等问题的接口,可以限制每个用户每几秒才能调用一次;
  2. 业务控制,例如创建用户的功能,可以在用户表中设置用户名字段为唯一索引,插入用户记录前先查询一下用户是否存在,存在则返回失败提示;电商中在购物车下单时,为了防止出现创建多个订单的情况,可以在订单表维护一个购物车标识的字段,下单时先校验该字段是否在订单表存在,存在则返回失败等等
  3. 注意状态机变化,很多业务会存在状态的流转,例如订单会存在未支付,支付中,支付成功,支付失败,退款等等状态,而且进行状态流转时,必须判断前置状态,否则不能更新,根据更新记录数量来判断是否更新失败,从而来做后续的业务操作 update order set status='支付成功' where status='支付中'
  • 分布式事务中的幂等控制
    分布式事务的解决方案有2PC,TCC,RocketMQ等,现在具体讲解下为什么这里需要分布式事务?
    以银行转账为例,用户A银行向B银行转账,A账户扣钱B账户加钱,如果是在同一个数据库,则直接通过数据库的事务保证,扣钱和加钱的逻辑要么都成功要么都失败;但是现实是两个银行,不可能用同一数据库,没法使用数据库的事务保证数据的完全一致性,但是实际上,我们肯定是要保证这两个操作最终的一致性的,就产生了分布式事务的解决方案。

第一种:2PC 理论可以参照文章 https://blog.csdn.net/w372426096/article/details/80449695
还是以银行转账为例,我们引入一个协调者,首先,协调者对A和B账户进行询问并且两个账户分别进行操作,但是不提交事务,我的理解是A账户增加一条冻结记录,并将可用余额扣减,冻结余额增加,如果执行成功返回YES,否则返回NO;B账户也是增加一条冻结流水,可用余额暂时不会增加,如果执行成功返回YES,否则返回NO;第二个阶段,协调者根据两个返回的值来判断下一步操作:如果都返回YES,则发送通知,让A的冻结余额扣除;B的可用余额增加;如果收到NO,则进行回滚,A的可用余额加回来,B的冻结记录删除。

第二种:3PC
在2PC的基础上,将第一个阶段一分为二,canCommit和preCommit,具体理论可以百度,3PC和2PC最大的区别是增加了超时自动提交的机制,当参与者处于preCommit或者commit时,如果由于网络或者协调者宕机等问题,导致参与者阻塞超时时,参与者也会自动提交,避免了2PC由于网络等问题导致的参与者长时间阻塞问题,分析了下原因,因为系统认为处于preCommit状态的参与者,极大概率是可以进行commit的,但是不能最终解决这种问题,因为
处于preCommit状态不一定最终就可以进行commit,可能某个参与者在preCommit执行失败,可能会导致最终的数据不一致性。

第三种:TCC 补偿型
还是以A银行账户向B银行账户转账为例,调用转账接口之前,先冻结A金额,并且插入转账记录,一般银行接口会提供幂等字段做查询用,然后调用银行转账接口;使用定时任务或者一部任务等拿这个幂等的字段去B银行查询,如果成功,则A金额解冻。TCC会有很多补偿性代码,当业务较复杂时,补偿性代码会很多。还有用MQ实现分布式事务的,RocketMQ支持分布式事务,它能保证A银行的插入转账记录和发送消息给B银行加钱这两个逻辑肯定会同时成功或者失败,但是我觉得最后可能还是会结合补偿代码进行结合来保障最终的一致性。

  • MQ重复消费
    1.通过消息id来做处理
    消息重复消费时,Message Id时一样的,我们在消费前可以先判断该消息有没有被消费过,消费过了就不做处理;但是message id不能确保唯一性,一般不建议使用此方法
    2.通过业务键保证幂等
    一般消息处理中会带有一个业务幂等键,通过此字段来做控制,此键一般作为主键,先从表中根据该字段查询出有没有记录,如果没有进行插入。

相关文章

  • 幂等系统设计

    1.系统为什么需要幂等 前端用户的操作问题导致表单重复提交,不做幂等控制会导致创建多个记录,例如用户下单,可能会导...

  • 数据幂等

    在系统设计的时候,操作幂等设计是一点需要考虑的点。 幂等(idempotent、idempotence)是一个数学...

  • 分布式锁:高并发下的幂等问题的"答案"

    写在前面:本文讨论的幂等问题,均为并发场景下的幂等问题。即系统本存在幂等设计,但是在并发场景下失效了。 一 摘要 ...

  • JAVA开发知识点集合

    分布式 分布式系统学习资料(ing) 理解HTTP幂等性消费幂等 Dubbo Dubbo架构设计详解 跨域 关于跨...

  • 接口的幂等性的N种考虑

    分布式服务接口的幂等性如何设计 什么是幂等性 一个分布式系统中的某个接口,要保证幂等性,该如何保证?这个事儿其实是...

  • 幂等性

    理解 HTTP 幂等性(15')系统幂等以及常用实现方式(10')分布式系统互斥性与幂等性问题的分析与解决(30')

  • SpringBoot接口幂等性实现的4种方案!

    目录 什么是幂等性 什么是接口幂等性 为什么需要实现幂等性 引入幂等性后对系统的影响 Restful API 接口...

  • 幂等设计

    为什么要做幂等? 幂等就是一个操作,不论执行多少次,产生的效果和返回的结果都是一样的。 例如 1、 前端重复提交选...

  • 幂等设计

    一种通过避免使用对象成员作为函数返回值的幂等设计 这样函数是独立的,无依赖 1.幂等设计减少了重复及嵌套调用的设计...

  • 03知识点

    05服务幂等设计 幂等定义 请求层面幂等 保证请求重复执行和执行一次的结果一致 业务层面幂等 同一用户不重复下单 ...

网友评论

      本文标题:幂等系统设计

      本文链接:https://www.haomeiwen.com/subject/vvqmpktx.html