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

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

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

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

会造成哪些问题呢?

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

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

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

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

实际场景分&析解决方案

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

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

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

场景1 的解决方案

  1. client处理

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

  1. 服务端处理
  • 带上token

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

  • 活锁CAS

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

场景2 的解决方案

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

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

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

场景3 的解决方案

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

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

总结

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

  • 前端需要保证下单后流程不回退
  • 唯一token校验防止重复
  • 依赖于上游服务校验防止重复
  • 每次下单都生成一单
  • 唯一索引
相关推荐
customer0818 分钟前
【开源免费】基于SpringBoot+Vue.JS个人博客系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
qq_4592384922 分钟前
SpringBoot整合Redis和Redision锁
spring boot·redis·后端
灰色人生qwer26 分钟前
SpringBoot 项目配置日志输出
java·spring boot·后端
阿华的代码王国42 分钟前
【从0做项目】Java搜索引擎(6)& 正则表达式鲨疯了&优化正文解析
java·后端·搜索引擎·正则表达式·java项目·从0到1做项目
EQUINOX11 小时前
lab4 CSAPP:Cachelab
java·后端·spring
customer081 小时前
【开源免费】基于SpringBoot+Vue.JS打卡健康评测系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
一小路一1 小时前
Go Web 开发基础:从入门到实战
服务器·前端·后端·面试·golang
(; ̄ェ ̄)。1 小时前
在Nodejs中使用kafka(三)offset偏移量控制策略,数据保存策略
分布式·后端·kafka·node.js
paterWang2 小时前
基于SpringBoot的驾校报名小程序系统设计与实现(源码+文档)
spring boot·后端·小程序
苏生Susheng4 小时前
【SpringBoot整合系列】Kafka的各种模式及Spring Boot整合的使用基础案例
java·spring boot·后端·spring·kafka·消息队列·并发