API的幂等性设计

一、背景

       API需要保证接口的幂等性,防止业务频繁刷API导致资源浪费,或者不小心重发消息影响业务。

二、解释

       接口的幂等,指一个操作重复执行N次得到的结果与执行一次是相等的。 

三、解决办法

       悲观锁,乐观锁,防重表,Token。

       3.1、悲观锁

                流程:

                         1、收到请求时,开启事务,对查询事件(如订单)加锁;

                         2、判断事件是否符合执行条件;

                         3、全部执行完毕后,提交或者回滚。

                缺点:执行时间长,悲观锁容易锁住整表,导致服务不可用问题。

                提示:排他锁

                select * from A for update

                缺点:MySQL的innerDB才使用,注意行锁和表锁与是否有索引/主键的区别。

        3.2、乐观锁

                 实现方式:通过版本号,在更新事件的时候锁表(大部分时间不锁表),比如:              

                 

                即使多个请求过来,因为进来的version是相同的,但是DB中的版本号已经被更新,修改条件不成立,也就是说不会被多次更新。

                缺点:使用主键或者唯一索引来更新,使用行锁而不是表锁。

         3.3、防重表

                 流程:

                        1、建立一张防重表,使用时间ID(比如订单号)作为唯一索引

                        2、在发起请求时,根据事件ID在防重表中新增一条记录

                 因为是唯一索引,重发的请求添加记录是不会成功的,第一个进入的事件可以被执行(事件完成后,可以删除防重表的记录)

                 缺点:多维护一张数据表,增加业务逻辑复杂度。

        3.4、Token

                 流程:

                        1、业务方在调用API的时候,在Header里传递一个X-Request-Id的参数(随机id,类似token)

                         2、平台接收到这次请求,判断在缓存里是否存在对应的X-Request-Id的对应记录

                         3、如果记录存在,标明这条消息已经被发送过,接口返回HTTP 412 Code

                         4、如果记录不存在,将该记录刷到缓存里,发送消息

                         5、Reaponse的Header也返回X-Request-Id

                   缺点:流程比防重表更加复杂。

                   Tips:使用Redis,和分布式锁一个道理。

四、幂等性的优缺点

        优点:

                1、实现接口的幂等性

                2、不需要关心随机ID的业务逻辑

        缺点:

                 1、增加了实现的复杂度

                 2、增加运维成本

五、总结

            基于我们当前的业务现状,使用 X-Request-Id + 缓存来支持消息 API 的幂等操作。虽然方案依赖 Redis, 但是平台本身就有使用缓存, 运维成本这个缺点可忽略不计, 逻辑实现相对简单。 综上可以设施

 

posted on 2023-08-22 15:20  木乃伊人  阅读(74)  评论(0编辑  收藏  举报

导航