分布式业务幂等性设计

2019-10-27 架构

幂等性理论

如果一个业务多次执行和只执行一次的影响是相同的,那么这个业务就是幂等性的。

f(x)=f(f(x))

Restful 规范的 GET 就是天然幂等的,重复请求不会产生不一样的影响

并发场景下,如果一个系统依赖的组件幂等,那么该系统在天然幂等。

实现方案

多个方向、多种方案可以实现接口的幂等,需要结合实际场景来决定具体策略。

唯一索引

在表中设计一个字段作为唯一索引实现插入去重。当然根据业务也可以采用联合唯一索引,当然列越少越好。

使用 token

典型例子就是防止表单重新提交。

  • 后端生成一个带有效期的 token 返回前端
  • 前端将 token 字段放入表单中,然后再将业务数据提交给后台
  • 后端验证 token 有效期通过后则进行 delete,若操作成功则生成新的 token 返回给前端
  • 提前申请单次有效

若先查询再 delete,存在并发的危险;当然可以采用分布式锁的方式进行 token 的 delete,但是这样做增加了复杂度。

乐观锁和悲观锁

从数据库层面实现数据加锁,业务场景允许的情况下采用乐观锁和悲观锁进行数据更新防重。

-- 乐观(id 最好是主键或唯一索引)
update tb set col='new val',ver='new version'
  where id='id' and col='old val' and ver='old version';
-- 悲观
select col from tb where id='id' for update;
update tb set col='new val' where id='id';
commit;

分布式锁

采用分布式锁对系统业务要求较高,一方面系统需要能处理分布式锁调用异常场景下的各种问题,一方面分布式锁也引入了性能消耗;

常见的分布式锁可以采用 redis、zookeeper 等。更多可看下之前的文章 分布式锁设计

对外 API 接口幂等设计

必传字段

两个必传的字段 source 来源、seq 序列号;两个字段作为防重判断的依据条件。

内部业务

内部业务将这两个字段进行组合,作为请求判读的依据,采用上述的各种方案即可实现幂等接口设计。

Search

    Post Directory