接口幂等性
什么是接口幂等性?
是指同一个接口,多次发出同一个请求,必须保证操作只执行一次;调用接口发生异常并且重复尝试时,总是会给系统造成无法承受的损失;所以需要阻止这种现象的发生;
比如支付接口,重复执行支付可能会导致多次扣钱; 订单接口, 重复执行的话同一个订单可能会多次创建;
为什么会产生接口幂等性问题?
- 网络波动,可能会引起重复请求;
- 使用了失效或超时重传机制(Nginx 重试, RPC重试或业务层重试等);
- 页面重复刷新;
- 使用浏览器后退按钮重复之前的操作,导致重复提交表单;
- 用户双击提交按钮;
主要分两种场景:
- 前端调用
- 其他服务调用
如何解决幂等性问题
前端解决
- 页面控制
按钮点击之后不可以重复点击, 避免用户重复点击多次, 生成相同的数据;
- 使用Post/Redirect/Get模式
PRG 模式, 主要目的是避免在用户刷新页面时重新提交表单数据, 从而避免重复提交的问题; 通过重定向, 可以将用户从一个处理请求的页面导向另一个展示结果的页面, 保持了用户体验的一致性;
PRG 模式的关键是将表单提交的处理和重定向分离开; 服务端在处理表单提交后, 将重定向的URL作为响应返回给客户端, 由客户端进行跳转; 这样可以确保用户刷新页面时, 浏览器只会发送 GET 请求, 而不会再次提交 POST 请求;
- Token 机制
功能上允许重复提交, 但是保证重复提交不会产生副作用; 比如n次只产生一条记录, 客户端每次请求都需要携带一个唯一的token, 服务器则验证token的有效性; 如果服务器收到了一个已经使用过的Token;则认为是重复请求并拒绝处理, 信儿确保接口的幂等性;
Token 机制常用来确保接口幂等性和防止重复请求,具体流程如下:
- 客户端发送请求到服务器;
- 服务器在响应中返回一个Token给客户端; 这个Token是随机生成的字符串或者其他的唯一标识符;
- 客户端在后续的请求中携带Token, 作为请求参数放在请求头中;
- 服务器在接收到请求时, 首先验证Token的有效性;
- 如果Token有效, 则是合法请求, 服务器进行正常处理;
- 如果Token无效, 说明是重复请求, 服务器拒绝处理, 并返回错误响应;
后端解决
在接口的处理逻辑中, 通过一些特定的标识符或请求参数来校验请求的幂等性, 确保同样地请求不会被重复处理;
- 唯一标识符
在每次请求中, 客户端可以生成一个唯一的标识符, 并将其作为请求一部分传送到服务器; 服务器收到请求时,先检查该标识符是否已经存在,如果存在, 则认为是一个重复请求; 服务器会忽略该请求或者返回相应结果; 如果不存在,则可以继续处理请求, 并将标识符保存到系统中, 方便后续校验;
- 请求参数
使用某些请求参数用来校验请求的幂等性; 可以使用时间戳作为请求参数, 在处理请求时,服务器验证时间戳与系统当前时间的差距是否在一个合理范围内, 如果差距过大, 则认为是一个重复请求, 服务器忽略或返回相应结果;
- 状态检查
在处理请求前, 服务器可以先检查系统中某个特定状态是否存在或满足特定条件; 如果已经存在或满足条件, 则认为是一个重复请求, 服务器就忽略或返回相应结果;