如何保证幂等性

什么是幂等性?

调用方对系统进行重复的调用,不管调用多少次,调用对系统的影响都是相同的。系统默认认为外部系统调用失败是常态,失败之后会有重试。
如何保证幂等性_第1张图片

什么情况下会导致幂等性问题?

  • 网络波动,可能引起重复请求
  • 用户重复操作,可能导致触发多次请求。
  • 业务接口调用的失败重试
  • 页面重复刷新
  • 用户双击按钮,导致重复提交
  • 消息队列消费失败重试。

保持幂等性有什么不足?

幂等性虽然简化了客户端的操作,但是以服务端逻辑变为复杂为代价,除非有特殊业务要求,否则,尽量不要保证幂等行

  • 增加了保证幂等性的业务逻辑,增加了业务代码的复杂度
  • 并行代码改为了串行代码,降低了代码的执行效率

如何解决幂等性问题

  • 查一下上次执行状态,没有则进行第一次的请求
  • 在服务状态改变前,增加放置重复提交的逻辑
  • token机制解决幂等性问题
    如何保证幂等性_第2张图片
    • token机制可能存在的问题
      • 先执行业务再删除token时
        • A执行完业务,还没有删除缓存,B请求到达携带token通过验证
          • 加拍他锁,保证执行业务和删除缓存为原子操作
          • 利用redis的原子指令incr,以token作为key,进行自增,保存时为1,第一次请求返回结果为2,则正常请求,否则,为重复请求。
      • 先删除token,再执行业务
        • 如果第一次请求超时,或者执行失败,没有响应,第二次请求重试时,认为重复请求,没法执行。
          • 一个token代表一个请求,可以返回接口异常,客户端重新获取token请求服务端。
    • token机制缺点
      • 每次业务请求都要多一次token的请求,成千上万的请求中只有十几个是失败的,为了少量的失败,增加一次请求是一种资源的浪费。
  • 乐观锁机制

数据库增加一个version字段,更新前判定版本号,版本号为预期版本号就执行更新,否则更新失败。或者加一个时间戳字段,更新时校验时间戳

如何保证幂等性_第3张图片

  • 适合更新场景
    • 缺点:
      • 对数据库有压力
      • 代码侵入性
      • 业务复杂时,可能存在ABA问题(版本号自增)。
  • 悲观锁机制解决幂等性

每次去操作数据时,都觉得别人中途会修改,所以每次在拿数据的时候都会上锁,加锁,再配合事务解决幂等性问题。
如何保证幂等性_第4张图片

  • 适用更新场景

  • 查询条件必须是索引,不然会锁表

  • 锁住记录,别的请求只能等待,事务太长,影响性能。

  • select + insert+update (主键或者唯一标识)
    如何保证幂等性_第5张图片
    如果重复概率低,可以直接insert+唯一标识(主键)捕捉异常返回成功。

  • 状态机幂等

    • 有些数据存在多种状态,可以利用状态机来处理幂等。
      如何保证幂等性_第6张图片
  • 防重表去重

建一种去重表,然后使用唯一索引,将更新语句与操作去重表的逻辑放在一个事务里面,异常会回滚

如何保证幂等性_第7张图片

  • 分布式锁幂等

请求过来时,先去尝试获得分布式锁,如果获得成功,就执行业务逻辑,反之获取失败的话,就舍弃请求直接返回成功
如何保证幂等性_第8张图片

你可能感兴趣的:(分布式,分布式)