关于防重,我是这么设计的

几年前,设计了一套增值服务购买流程,当时设计一整套下单购买流程。当时看了我们项目中多个订单防重,发现都不一样。结合了一点自己的思考,设计了一整套流程。当时感觉没什么,面试一问全扒瞎,特此回顾一下。

重复提交是项目中最常遇到的一个问题。为啥?不好界定啊,比如

  • 用户就是要买两单,手速快了点,防重了就不合适。
  • 大商户就是要用工具刷,就突出一个合理。
  • 前端忘记防抖,没辙。
  • 接口失败重试,机制就是这个机制
  • 队列重复消费了,也算是一种吧

会造成哪些问题呢?

  • 比如重复扣减库存?
  • 比如多加积分?
  • 比如重复下单?

场景还有很多,一般核心的业务场景都是要做预防的,具体哪些就要根据业务场景来考虑了

至于怎么解决,首先有两个概念,防重和幂等

  • 防重:防止重复提交,对于结果没有严格要求
  • 幂等:通俗点来说是防重的子集,再防重的基础上要求返回的结果一致

实际场景分&析解决方案

一个精简版的下单流程就是下面这个样子,下面就根据这个场景来聊一下防重。不谈场景就谈方案都是***!!!!

就拿上面的场景来说,我标注的三个地方都有可能发生重复提交的场景

  • 场景1:客户端重复网络抖动,前端重复提交,页面重复进入。此处的重复提交基本上都和客户端和网络还有用户脱不了关系
  • 场景2:可能得点就是重复消费,失败重复调用的场景。此处防重一般是第三方来考虑,稍后我也会分析分析。
  • 场景3:这个场景多半就是失败重试了。跟第三方,最大努力通知相关。

场景1 的解决方案

  1. client处理

一般来说,前端要做到流程不回退,防抖等操作,这个很重要,可以解决很大一部分重复请求

  1. 服务端处理
  • 带上token

请求的时候,可以前端台上token,或者后台提供token服务来解决这个问题,此token要保证特定时间内唯一性

  • 活锁CAS

如果不使用token也不使用redis,可以通过cas改变修改其他表的状态或者库存的方式,如果成功,才进行后续的订单创建

场景2 的解决方案

这个场景一般是三方服务要考虑的场景了,根据我对接调试的经验,一般是一种。

每次请求都生成一个订单,保证订单id唯一。每次请求都是新的一单,不会乱,出现问题也都是调用方的问题。一般的支付渠道也都是一次请求一单。

但是不能防止恶意请求的方式,为了解决这个问题,三方都会带上非对称加解密的方式进行请求校验。

场景3 的解决方案

第三个场景呢,也是在支付的时候会遇到的情况。有的支付渠道防控做的不大好,就是会有重复调用的情况。关键通知的时间不可控,一般来说是10分钟,20分钟,xxxxx进行累加。时间跨度比较大,也比较容易。

  • 根据己方或者三方订单号进行查询,判断,这种可以防止时间跨度比较大的情况
  • 唯一索引进行兜底,避免并发情况。

总结

当时设计的时候,防重部分,参考了项目中的蛮多案例的。这里只把一个下单流程中防重的点拿出来分析,适用性比较广。方案算不上高大上,但是适用性还可以,我觉得可以cover大部分场景,。

  • 前端需要保证下单后流程不回退
  • 唯一token校验防止重复
  • 依赖于上游服务校验防止重复
  • 每次下单都生成一单
  • 唯一索引
相关推荐
kingbal18 分钟前
SpringCloud:Injection of resource dependencies failed
后端·spring·spring cloud
刘天远1 小时前
django实现paypal订阅记录
后端·python·django
ℳ₯㎕ddzོꦿ࿐1 小时前
Spring Boot集成MyBatis-Plus:自定义拦截器实现动态表名切换
spring boot·后端·mybatis
逸风尊者1 小时前
开发也能看懂的大模型:RNN
java·后端·算法
小钟不想敲代码3 小时前
第4章 Spring Boot自动配置
java·spring boot·后端
hummhumm3 小时前
第33章 - Go语言 云原生开发
java·开发语言·后端·python·sql·云原生·golang
AskHarries4 小时前
利用 OSHI获取机器的硬件信息
java·后端
凡人的AI工具箱4 小时前
40分钟学 Go 语言高并发:【实战】并发安全的配置管理器(功能扩展)
开发语言·后端·安全·架构·golang
我的运维人生4 小时前
Spring Boot应用开发实战:构建RESTful API服务
spring boot·后端·restful·运维开发·技术共享
颜淡慕潇4 小时前
【K8S系列】深入解析 Kubernetes 中的 Deployment
后端·云原生·容器·kubernetes