乐趣区

关于api:支持API幂等操作

背景

平台有局部 API 须要保障接口幂等性,避免业务频繁刷 API 造成资源节约,或者不小心重发消息影响业务。

名词解释

接口的 幂等,指的是一个操作反复执行 N 次失去的后果(副作用)与执行一次是相等的。比方在 HTTP 协定中,GET 申请,会失去同样的数据。然而对于 POST 和 PATCH 的接口,每次申请动作失去后果都是不同,这里是不幂等的,而有的是时候对接口有幂等的要求。

比方银行的转账,因为各种起因可能同一个申请会被屡次发送,然而后果只会胜利转账一次,其余转账不会失效。

解决方案

目前业界有绝对成熟的解决方案,包含 乐观锁,乐观锁,防重表和应用 Token。上面别离介绍以上 4 种解决方案。

乐观锁

流程:

  1. 申请过去的时候开启事务,对查问事件(比方订单)加锁
  2. 判断事件是否合乎执行条件
  3. 在全副执行完后,提交或回滚

毛病:执行工夫长,乐观锁容易锁住整表,导致服务不可用问题。

乐观锁

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

UPDATE table set usage=usage+1, version=version+1 where uuid = XXX and version = XXX 

即便多个申请过去,因为进来的 version 是雷同的,然而 DB 中的版本号曾经被更新, 批改条件不成立,也就是说不会被屡次更新。

毛病 :应用 主键 或 惟一索引 来更新,应用 行锁 而不是 表锁

防重表

流程:

  1. 建设一张防重表,应用事件 ID (比方订单号) 作为惟一索引
  2. 在发动申请时依据事件 ID 在 防重表 中新增一条记录

因为是 惟一索引,重发的申请增加记录不会胜利,第一个进入的事件能够被执行(事件实现后,能够删除防重表的记录)

毛病:多保护一张数据表,减少业务逻辑复杂度。

应用 Token

流程:

  1. 业务方在调用 API 的时候,在 Header 里传递一个 X-Request-Id 参数(随机 id, 相似 token)
  2. 平台接管到这次申请,判断在 缓存 里是否存在对应 X-Request-Id 对应的记录:

    • 如果记录存在,表明这条音讯曾经被发送过,接口返回 HTTP 412 Code
    • 如果记录不存在,将该记录刷到缓存里,发送音讯
  3. Response 的 Header 也返回 X-Request-Id

毛病:流程比防重表更简单。

幂等性优缺点

长处:

  1. 实现接口的幂等性
  2. 不须要关怀随机 id 的业务逻辑

毛病:

  1. 减少了实现的复杂度
  2. 减少运维老本

总结

基于咱们以后的业务现状,应用 X-Request-Id + 缓存来反对音讯 API 的幂等操作。尽管计划依赖 Redis, 然而平台自身就有应用缓存,运维老本这个毛病可忽略不计,逻辑实现绝对简略。综上能够设施。

参考

  • 在 API 中实现幂等性
退出移动版