一个简单问题引发的接口幂等思考

What—什么是接口幂等性校验?

有时候对于一些特殊场景,为了避免数据重复,会做接口幂等性校验

比如支付订单的时候,对于同一个订单,如果重复调用支付接口,需要保证只扣款一次

接口的幂等主要是为了保证防止因为网络波动、重试机制、用户误操作等原因,导致一个接口被多次调用,从而产生了不合理的错误数据

How—常见的实现方式

  • 基于数据库的唯一索引
    • 原理:在数据库表中,对某些关键字段设置唯一索引。当接口被调用时,相关数据插入数据库,如果是重复请求,由于唯一索引的存在,第二次及以后的插入操作会失败,从而保证了幂等性。
    • 示例:对于支付接口,如果订单号是唯一的,可以在订单表的订单号字段上设置唯一索引。当支付请求到来时,首先会尝试插入包含订单号等相关信息的记录,如果订单号已经存在,说明是重复请求,直接返回之前的处理结果。
  • 使用状态机
    • 原理:通过定义对象的状态以及状态之间的转换规则来实现幂等性。接口的每次调用都对应着对象状态的一次转换,当重复调用时,如果对象已经处于目标状态,则不再进行实际的业务处理。
    • 示例:在订单处理系统中,订单有 “已创建”“已支付”“已发货” 等状态。当支付接口被调用时,如果订单状态已经是 “已支付”,则直接返回成功结果,不再进行支付操作。
  • 基于 Token 机制
    • 原理:客户端在第一次请求时生成一个唯一的 Token,并随请求发送到服务端。服务端接收到请求后,首先检查该 Token 是否已经处理过,如果是,则直接返回上次的处理结果,不再进行重复处理。
    • 示例:用户在提交表单时,客户端生成一个 Token 并添加到表单数据中。服务端接收到表单请求后,对 Token 进行验证,如果发现该 Token 已经存在于已处理的 Token 列表中,就认为是重复请求,按照之前的处理方式返回结果。

Where—应用场景

  • 金融交易系统
    • 在支付、转账等操作中,幂等性校验至关重要。如果没有幂等性保证,可能会导致用户资金被多次扣除或错误增加,严重影响金融安全和用户利益。
  • 电商订单系统
    • 订单的创建、支付、发货等操作都需要幂等性校验。例如,防止重复创建订单、多次支付同一订单以及重复发货等问题。
  • 消息队列消费
    • 当消息队列中的消息被重复消费时,如果没有幂等性处理,可能会导致业务逻辑多次执行,产生错误的结果。例如,对一条订单创建消息进行多次处理,可能会创建多个相同的订单。

问题分析

有这样一个问题,大概业务场景可以简单抽象为下图描述:
在这里插入图片描述

设计用例的时候,针对SC发送的库存变动消息,设计了相同商品多次调用接口的场景,测试PC是否会过滤掉重复的数据,保证DB内记录的唯一性,经过测试,该条用例执行通过

但是在生产环境,用户的列表页面,还是发现了有重复数据,最后经过排查,复现了该场景:

同一个商品变更,多次调用接口,代码已经做了处理不会重复插入数据;

单次调用接口时,参数中存在重复商品,此时就忽略了这种场景的处理,导致数据重复插入

问题定位成功,很快就解决了。

分析思路

经过此次问题,通过复盘和资料查阅,总结出来几点关于幂等性问题分析的思路,当列表中出现重复数据的时候,一般我们可以按照以下排查思路来定位问题并分析:

  1. 数据录入环节排查
    1. 用户操作层面
      1. 检查输入方式:查看是否存在用户手动输入数据时,因误操作(如多次点击提交按钮、复制粘贴数据多次等)导致重复数据录入的情况。
      2. 核实输入规则:确认系统是否对用户输入设置了明确的限制和规则,以防止重复数据的产生。比如,是否要求订单编号必须唯一。
    2. 数据导入层面
      1. 检查导入文件:若数据是通过文件导入的方式进入系统的,检查导入文件本身是否存在重复记录。
      2. 核实导入流程:检查导入流程是否对文件内的重复数据做了校验或者去重。
  2. 系统业务逻辑层面排查
    1. 数据生成规则
      1. 检查自动生成规则:对于系统自动生成的数据(如订单号、流水号等),要检查生成规则是否存在缺陷,导致有可能生成相同的值。
      2. 核实唯一性约束:确认系统业务逻辑中对关键数据是否设置了足够的唯一性约束。(如用户名、账号名等信息在系统中要严格约束,确认唯一性)
    2. 数据更新与同步
      1. 检查更新操作:当数据在系统中进行更新时,要留意是否会因更新操作不当而产生重复数据。
      2. 核实同步机制:若系统涉及多个模块或子系统之间的数据同步,要检查同步机制是否正常运作。
  3. 数据库层面排查
    1. 表结构与索引
      1. 检查唯一性索引:查看数据库表中是否针对关键列(如订单表中的订单号列)设置了唯一性索引。
      2. 核实表结构合理性:审查数据库表的结构设计是否合理,是否存在容易导致重复数据产生的因素。比如,在一个多对多关系的表中,如果关联关系设置不合理,可能会导致某些数据在关联表中出现重复记录。
    2. 数据库事务处理
      1. 检查事务隔离级别:了解数据库事务的隔离级别设置,不同的隔离级别可能会对数据的一致性和重复性产生影响。例如,在可重复读隔离级别下,如果事务处理不当,可能会导致在同一事务内读取到重复的数据。
      2. 核实事务完整性:确认数据库事务在执行过程中是否保持完整性,即是否能够保证所有相关操作(如插入、更新、删除等)都能按照预期完成,不会因为部分操作失败而导致数据出现重复或不一致的情况。
  4. 缓存层面排查
    1. 缓存策略与数据更新
      1. 检查缓存机制:查看系统是否使用了缓存,如果使用了缓存,要检查缓存的策略是否合理,是否会导致重复数据出现。
      2. 核实缓存更新时间:确定缓存更新的时间间隔或触发条件是否合适。
  5. 第三方接口或服务排查
    1. 接口调用与数据返回
      1. 检查接口调用情况:若系统与第三方接口或服务有交互,要检查在调用这些接口时是否会带来重复数据。(相同数据多次调用,单次调用含重复数据的参数)
      2. 核实服务可靠性:评估第三方服务的可靠性,看是否存在因为第三方服务故障或错误操作而导致系统接收并处理重复数据的情况。

以上就是关于接口幂等性的介绍与分享。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值