一、重复原因
造成重复下单的原因有很多,比如用户重复提交、网络超时导致的重试(网关超时重试、RPC超时重试,以及前端超时重试等),下单请求的整个链路都可能造成重复,大致可以分成如下三类:
- 用户重复提交;
- 恶意刷单;
- 网络原因导致的超时重试;
二、产品方案
如何防止用户重复下单,并不只是技术的事情,因为技术并不一定能百分百的考虑到所有可能重复的场景,必须依靠产品+技术共同的努力,以及运营、客服等订单重复时的事后处理。
- 用户点击”提交订单“按钮后,对按钮置灰,禁止再次提交;
- 对于涉及金额比较大的订单,需要弹窗二次确认;
- 对用户的下单频率、次数进行限制;
三、技术方案
用户下单在逻辑上是一个非幂等行为,因此解决方案都是基于物理去重的思路设计的,用某个id表示某次下单行为,通过该id判断是否重复;
3.1 基于订单号去重
- 用户进入下单页面时,前端页面先调用订单服务得到一个订单号;
- 用户提交订单时,携带得到的订单号,向后端发送创建订单请求;
- 接收到创建订单请求后,订单系统校验订单号是否合法,以及是否已被缓存;
- 如果存在,说明订单合法,将订单号作为唯一主键在数据库中创建订单;
3.2 基于唯一ID去重
- 用户进入下页面时,前端页面自己生成一个全局唯一的ID;
- 用户提交订单时,在创建订单的请求中带着这个ID;
- 接收到下单请求后,订单服务首先会利用缓存的CAS操作设置ID;
- 如果之前不存在则成功,数据库创建订单;如果已经存在则返回;
参考:
- https://cloud.tencent.com/developer/article/1121727