开发中遇到的问题&解决方案(十二)

简介: 由于之前做过贷款平台和电商平台,所以对于订单这个东西十分的敏感,有段时间有点疯狂的喜欢逮着京东、淘宝、拼多多的订单页看,思考别人在做的购物车和订单这块是怎么实现的,尝试找找Bug什么的,后面出去面试别人看我的项目也会问一些关于订单如何设计和实现的问题,所以感觉这个东西还是有讲的必要,下面进入主题。

微信截图_20220531133417.png

前言


由于之前做过贷款平台和电商平台,所以对于订单这个东西十分的敏感,有段时间有点疯狂的喜欢逮着京东、淘宝、拼多多的订单页看,思考别人在做的购物车和订单这块是怎么实现的,尝试找找Bug什么的,后面出去面试别人看我的项目也会问一些关于订单如何设计和实现的问题,所以感觉这个东西还是有讲的必要,下面进入主题。


一.订单号出现重复


1)一般订单号


一般订单号的生成规则为:订单类别(场景)+随机数字+时间戳,这种订单号会出现重复的情况吗?答案是会的,然后前端没有做“防连点”,那么这种订单号可能会出现重复


2)UUID类订单号 UUID一般不会重复,但是一般不用其作为订单号,原因是位数太长,不建议使用

UUID.randomUUID()
007a82b5-9f9c-4809-9fec-9b20ca3183d9
复制代码


3)复杂的订单号


复杂的订单号生成规则:1~2位订单识别码+7位时间戳+6位(用户id加密&随机数)


二.订单状态


在常规情况下,订单的状态是不会出现问题的但是当高并发情况出现时,订单状态有可能会发生错误,而且一个订单从用户下单的待提交、提交、待支付、支付、待发货、发货、收货、退货、退款等状态是很多的,也许还有很多的中间状态,就是枚举类也要写一堆代码吧,而且还不能保证在节点上状态是正常流转到下一个节点的。那有没有好的解决办法呢?答案也是肯定的,它就是Spring Statemachine(状态机), 其支持状态的嵌套,状态的并行(parallel,fork,join)并且是根据事件驱动状态,类似Activiti的节点流程工作原理,感兴趣的小伙伴可以去看看


三.订单超时取消 待支付到支付之间可能存在订单取消的情况,那订单取消如何去设计才能更好呢?下面我们来看看这些设计方案的优缺点


1)定时任务扫描 很多人在开始设计这个功能的时候的第一个思路估计都是写个定时任务去扫描订单表,然后计算时间差满足取消时间就更新订单状态为取消,这种方案我在之前的系统里见过,但是存在问题,如果去扫描时恰恰时间差错过那么就不能按时间取消得到下一轮才能取消,还有就是订单表动辄几十万到几百万的数据,扫描一遍耗时太长,会给数据库增加压力


2)java的延时队列DelayedQuene,即将下单待支付的订单放入队列里,然后在规定的时间内把队列里的订单拿出来比较,如果超过规定时间则触发取消订单操作,这种方案同样存在错过时间差的情况,而且如果用的是自带的DelayedQuene,如果服务重启里面的数据也会一起消失


3)Rocketmq发送延时消息,这个目前比较靠谱,原理是生产者整合订单信息发送给消费者,中间有监听,在规定的时间内消息没有到达则代表已超时,则可以取消订单,这种方案下时间目前没有支持扩展,如果不满足要求得重写一下

messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
复制代码


小结


其实关于订单还有非常多的点值得我们去关注和重视,上述的解决方案也是个人项目经历后总结,也会存在理解不到位的地方

目录
相关文章
|
存储
【数据结构】连通图、连通分量与强连通图、强连通分量—区别在于强,强强在哪里?
【数据结构】连通图、连通分量与强连通图、强连通分量—区别在于强,强强在哪里?
11606 1
【数据结构】连通图、连通分量与强连通图、强连通分量—区别在于强,强强在哪里?
|
8月前
Mac 上怎么安装 IDEA 2020.1.dmg?简单几步搞定(附安装包)
下载IDEA 2020.1.dmg文件后,双击打开并拖拽IntelliJ IDEA图标至“Applications”文件夹,等待复制完成。随后通过启动台或应用程序文件夹打开软件,首次运行时点击“打开”确认信任。安装成功,即可开始编程!(238字)
|
人工智能 负载均衡 监控
使用 Go 和 Gin 实现高可用负载均衡代理服务器
本文基于Go语言和Gin框架,实现了一个企业级负载均衡代理服务器,支持动态路由、健康检查、会话保持等功能。具备高可用性与高性能,单节点支持100k+ QPS,延迟达亚毫秒级,并提供完整的压力测试方案与优化建议。
381 7
|
9月前
|
数据采集 人工智能 自然语言处理
Playwright MCP 浏览器自动化框架全面解析
Playwright MCP是微软推出的开源项目,结合Playwright与MCP协议,让AI通过结构化数据直接操作浏览器。告别传统视觉识别,实现高效、精准的网页自动化,广泛应用于测试、爬虫、办公自动化等场景,大幅提升效率与可靠性。
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
1435 2
|
存储 Java 程序员
Java 中的堆栈和堆有什么区别?
【8月更文挑战第22天】
810 0
|
SQL NoSQL 数据可视化
【国庆弯道超车系列】MongoDB进阶之查询(一)
【国庆弯道超车系列】MongoDB进阶之查询(一)
488 0
目标如何设定:7 分钟重新认识 SMART 原则。
你有过很多目标,但都没达成。于是你找到了一种解决方案——SMART 目标管理原则。它是五个单词首字母的缩写——Specific、Measurable、Achievable、Relevant 和 Time-bound——你的目标必须是具体的、可衡量的、可达到的、和其他目标相关的、有时间限制的。
1249 0
|
存储 监控 Java
Java多线程优化:提高线程池性能的技巧与实践
【4月更文挑战第6天】Java并发编程中,线程池通过重用线程降低性能开销,控制并发级别。关键在于理解线程池工作原理:核心线程数、最大线程数、队列和拒绝策略。优化技巧包括合理设置线程池大小、选择合适队列、避免过度使用、自定义拒绝策略和正确关闭线程池。I/O密集型应用案例:大核心线程数、使用 `CachedThreadPool`、`LinkedBlockingQueue` 和定制拒绝策略。正确配置和管理线程池对提升应用性能至关重要。
957 3
|
消息中间件 Java 中间件
如何在Java项目中实现分布式事务管理
如何在Java项目中实现分布式事务管理