龙空技术网

一文搞定:什么是接口幂等性?怎么测试?

爱软测 131

前言:

现在同学们对“数据交互接口类型”大致比较看重,我们都需要学习一些“数据交互接口类型”的相关内容。那么小编同时在网络上搜集了一些关于“数据交互接口类型””的相关内容,希望兄弟们能喜欢,大家一起来学习一下吧!

#01 接口幂等性

概念

同一个接口,多次发出同一个请求必须保证操作只执行一次。 也就是指用户对于同一个接口发起的一次请求或者多次请求的结果是一致的,不会因为多次请求而产生不同的结果。

应用场景

· 前端重复提交:例如订单接口,用户连续多次点击下单操作,导致后端收到多条请求,同一个订单可能会多次创建。

· 接口超时重试:例如支付接口,当调第三方接口时,可能由于网络等原因导致调用失败而多次调用,出现多次扣款的情况。

· 消息重复消费:例如MQ消息中间件在生产端和消费端都有重试机制,也就是说同一消息可能被重复消费的问题。

#02 接口幂等处理方式

前端和后端交互的接口,前端可以将按钮置灰、不可点击、或者跳转到其他页面,可以防止一部分前端进行重复提交。但如果是模拟请求调用服务的话,就需要后端进行幂等性处理了。

数据库悲观锁

场景:当要对数据库中的一条数据进行修改时,为了避免同时被其他人修改,最好的办法就是将该数据进行加锁以防止并发;那么在高并发的情况下,会造成一个业务被执行两次的情况发生,我们可以通过悲观锁实现,也就是在sql查询语句中添加for update字段。

如果在操作过程中执行了for update,此时就会对这行记录上锁,直到整个操作完成提交事务之前,其他操作走这个查询都会进入到阻塞状态。

数据库乐观锁

场景:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断在此期间别人有没有去更新这个数据,可以通过在表中新增一个version(版本号)字段,当更新数据时首先和版本号作对比,如果不相等说明已经有其他的请求去更新数据了,提示更新失败。

状态机制

在日常业务很多都有流转状态,比如订单业务,有待支付、已支付、待发货、待收货、已完成、已取消等状态。

我们可以通过定义status状态字段,在进行更新操作时使用对应的状态来实现幂等性。

数据库唯一索引

悲观锁、乐观锁、状态机制都是作用于update操作来实现幂等性,而唯一索引是针对insert操作来保证幂等。

当插入数据时,按照唯一索引进行插入,比如:相同的订单号就不可能往数据库中插入两次。重复插入直接返回异常

这个机制是利用了数据库的主键唯一索引的特性,保证了数据的唯一性。

数据库去重表

往去重表里插入数据的时候,利用数据库的唯一索引特性,保证数据的幂等性。

唯一序列号可以是一个字段,也可以是多字段组成的值。

比如:当使用订单号作为去重表的唯一索引,每次请求都根据订单号向去重表中插入一条数据。

第一次请求查询订单支付状态时,订单没有支付,再进行支付操作,执行完后更新订单状态为成功或失败,删除去重表中的数据。

后续的订单因为表中唯一素引而插入失败,则返回操作失败。去重表作用是加锁的功能。

Redis实现

Redis实现的方式就是将唯一序列号作为Key,唯一序列号可以是一个字段,也可以是多字段组成的值。例如:订单表的订单号,大多是多个字段的唯一性组合。

同时需要设置一个key的过期时间,否则 Redis 中会存在过多的 key。

当用户发起请求时,服务端收集数据并且生成订单号code作为唯一序列号,将该订单code设置到Redis中,同时设置超时时间,判断是否设置成功,如果设置成功,说明是第一次请求,则进行数据操作;如果设置失败,说明是重复请求,则直接返回成功。

token机制

token机制每一次操作生成一个唯一性的凭证,需要前后端进行一定程度的交互来完成。

主要流程:

▹ 服务端提供获取token接口,供客户端进行使用。服务端生成token后,如果当前为分布式架构,将token存放于redis中,如果是单体架构,可以保存在jvm缓存中。

▹ 当客户端获取到token后,会携带着token发起请求。

▹ 服务端接收到客户端请求后,首先会判断该token在redis中是否存在。如果存在,则完成进行业务处理,业务处理完成后,再删除token。如果不存在,代表当前请求是重复请求,直接向客户端返回对应标识。

#03 幂等测试的关注点

需要关注业务性质和产品设计上是否需要做到幂等;

• 需要特别关注资金流动、订单变更等业务场景的失败重试机制;

• 前端测试可以通过快速点击,使用UI自动化手段进行实现;

• 后端接口使用jmeter或者postman工具多次重复发送参数相同的请求,查看服务器返回结果。

标签: #数据交互接口类型