2.幂等设计

2020-06-07  本文已影响0人  学海一乌鸦

1.定义及场景

定义:一次和多次请求某一个资源具有相同的副作用;
场景:系统解耦后,服务之间的调用可能有三种状态:成功(success)\失败(fail)\超时未知(timeout),前两种结果是明确的。但是第三种的超时则完全不知道是什么状态。
对于第三种情况,一般有两种解决办法:
一:提供相应的查询接口,根据得到的查询结果(成功\失败)去执行相应的流程。[这种方式存在的问题在于下游还没有处理完,得到的结果仍然是未知的或者是初始状态,没有达到終态,需要和下游约定好多长时间以后才可以去查询]
二:让上游根据拿原单号进行幂等重试,下游系统保证一次请求和多次请求的结果是一致的。

2.幂等设计的原则

方案一

当收到交易请求的时候,我们就会到这个存储中去查询。如果查找到了,那么就不再做处理了,并把上次处理的结果返回。如果没有查到,那么我们就继续执行流程。
这个的问题在于:绝大多数的请求都不是重复请求来的,但是这样的流程是100%去查询,会增加系统的耗时;


image.png

方案二

对于插入的场景:当这个存储出现冲突的时候会报错。也就是说,我们收到交易请求后,直接去存储里记录这条交易信息(相对于数据的 Insert 操作),如果出现冲突的异常,那么我们就知道这个之前已经有人发过来了,所以就不用再做了。比如,数据库中你可以使用 insert into … values … on DUPLICATE KEY UPDATE … 这样的操作。
对于更新的场景:如果只是状态更新,可以使用如下的方式。如果出错,要么是非法操作,要么是已被更新,要么是状态不对,总之多次调用是不会有副作用的。update table set status = “paid” where id = xxx and status = “unpaid”;

3.业务场景分析

3.1 幂等最初的方案

  1. 请求受理,从DB层面(利用数据库的唯一性索引)判断是否重复;从缓存层面判断是否重复;无重复跳到步骤2,重复跳到步骤3
  2. 无重复,幂等校验通过,继续执行后续的业务流程;
  3. 重复抛异常,外层捕获,此时要进行关键参数的比对(根据数据库的参数和请求的参数关键信息进行比对),如果相同,构造相同的成功结果返回;如果不相同,交易信息被篡改,抛出违反唯一性约束的异常;

3.2 当前场景存在的问题

1. 为什么使用DB+缓存的双重幂等措施?

DB存在容灾的情况,极端情况下,一笔请求在主库,第二笔请求由于容灾请求到了容灾库,幂等失效;即该方式只在单库单表的情况下有效;
缓存的设计:

2.当前幂等方案的优化

2.1 关键参数比对

2.2 识别幂等的处理方式多样化

2.3 幂等返回结果的调整

参考文档

上一篇下一篇

猜你喜欢

热点阅读