订单系统的设计和实现实践

疏影横斜水清浅,暗香浮动月黄昏。

1 前言

在电商项目开发中,订单系统是整个项目的核心,那么一个订单系统该如何着手设计并提供对应的能力呢,这是一个值得深思的问题。本文将结合项目实践经验,从设计角度出发,根据实际的业务要求着重分享几个核心的业务关键点和技术关键点。

2 设计理念和技术选型

订单系统是一个核心系统,其技术基本要求如下:

  • 1 高可用性,需要保证系统的4个9,服务需要采用集群部署,并且能够实现故障转移。
  • 2 高并发,每秒钟支持1000+的订单创建,需要使用异步处理和流量削峰。
  • 3 数据一致性,通过分布式事务和补偿机制保证核心业务的数据一致性。
  • 4 可扩展性,需要采用微服务架构,模块化设计实现业务开发的快速迭代。

对于技术选型,需要采用目前主流的框架。基础框架为SpringBoot3.x+SpringCloudAlibaba,数据存储和缓存采用 MySQL8+Redis7,消息队列使用rabbitmq实现异步解耦,分库分表工具使用 ShardingSphere5。此外还要有监控体系,推荐采用 Prometheus + Grafana。对于日志查询,可以使用 ELK 进行搭建。项目中使用的工具类为 Hutool, ORM 框架采用 mybatis-plus

3 核心模块设计

3.1 订单创建

订单创建时,需要防止订单的重复提交,保证幂等性。采用可靠的生单方案,推荐根据业务编号前缀和雪花算法生成订单号和订单明细号。

为了防止订单重复提交,在提交订单之前,需要先获取订单的请求号。在创建订单时需要判断订单号是否存在,防止订单的重复创建。此外这里的雪花算法生成算法使用 Hutool 里面的 Snowflake 进行创建。

3.2 订单状态流转

通常情况下,订单的状态如下所示:

scss 复制代码
[待支付] → (支付成功) → [已支付]  → [退款中]  → [退款完成|部分退款] 
           ↘ (超时未支付) → [已取消]
           ↘ (用户关单) → [已关闭]

对于状态的流转,可以使用状态机 Spring StateMachine 来控制状态的流转,但是在实际的操作中,很少采用这样的方式,因为实际状态相对比较复杂。通常会在业务代码中实现状态的流转和控制。

3.3 库存扣减方案

对于库存的扣减的方案,总的来说可以分为数据库扣减或者数据库+redis缓存的方式进行扣减:

  • 数据库扣减
bash 复制代码
1 根据商品id查询库存,校验商品的状态以及sku的状态
update tb_good_stock set stock_num=stock_num-count where sku_id= skuId and stock_num>= count;
  • 缓存扣减库存

    使用redis扣减库存,可以结合lua脚本操作商品库存的批量扣减,并且使用异步任务+操作日志将库存变化同步到数据库中。

根据业务的实际情况设计扣库存,库存扣减的时机分为两种,下单扣减库存和支付时扣减库存:

扣减方式 优势 缺点
下单时扣减库存 买家只要下单就能够买到商品 库存紧张时,买家拍下不付款,会影响其他买家下单。可能会存在恶意占库存的情况,导致商品售罄给卖家造成损失。
支付时扣减库存 库存不会长时间占用,当库存紧张时,会有更多机会买到商品。 用户支付成功后扣减库存,会出现扣减失败的方式,系统需要进行自动关单并退款,影响买家体验。
3.4 分布式事务

对于单机服务,可以使用本地事务来解决问题,但是对于微服务项目来说,就需要使用分布式事务。对于分布式事务,强一致性的场景可以使用 rocketmq 的事务消息或者使用 seta 来实现,对于一般的场景,可以使用本地消息表的方式来实现最终一致性。

3.5 分库分表方案

对于订单数据,订单表和订单明细表是需要进行分库分表的,分库的策略根据 userId 进行分库,分表的策略是根据 createTime 进行分表。此外,订单表和订单明细表的分库分表策略要保持一致,方便进行表关联的操作。另外,退款单表和退款明细表的分库分表策略和订单的策略保持一致。如果退款数据量比较小的话,可以使用分表策略即可,无需分库。

4 性能优化和任务补偿

4.1 任务补偿

对于任务补偿,主要是用于关闭超时未支付的订单,此外还要重试处理中的退款单。

4.2 性能优化
  • 1 对于热点数据,使用redis 进行缓存,比如字典数据,用户经常查询的订单。
  • 2 数据的读分离,通过 ShardingSphere 不仅可以实现分库分表,还可以通过配置实现读写分离。
  • 3 索引优化,对订单表里面经常的查询字段,可以建立联合索引,方便数据的查询。
  • 4 针对订单服务的接口,需要监控服务的 TPS/QPS 数据,通过链路分析查询业务的卡点,进行技术优化。
  • 5 监听 mysql 数据库的使用情况,线程池的使用效率以及慢sql数据,进行配置和查询的优化处理。

5 总结

本文通过订单服务的创建实践,介绍了订单系统设计的重点和核心内容。在设计系统的过程中中,会用到各种技术知识,需要综合运用,根据业务的实际需要进行取舍。通过订单系统将各种技术组合使用,实现业务系统的高效运行,提供可靠的服务能力。本文通过数据项目 github 地址 springboot-auth

相关推荐
程序员良辰1 小时前
Spring与SpringBoot:从手动挡到自动挡的Java开发进化论
java·spring boot·spring
鹦鹉0071 小时前
SpringAOP实现
java·服务器·前端·spring
练习时长两年半的程序员小胡2 小时前
JVM 性能调优实战:让系统性能 “飞” 起来的核心策略
java·jvm·性能调优·jvm调优
崎岖Qiu2 小时前
【JVM篇11】:分代回收与GC回收范围的分类详解
java·jvm·后端·面试
27669582924 小时前
东方航空 m端 wasm req res分析
java·python·node·wasm·东方航空·东航·东方航空m端
许苑向上4 小时前
Spring Boot 自动装配底层源码实现详解
java·spring boot·后端
喵叔哟5 小时前
31.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--单体转微服务--财务服务--收支分类
java·微服务·.net
codu4u13145 小时前
Maven中的bom和父依赖
java·linux·maven
呦呦鹿鸣Rzh5 小时前
微服务快速入门
java·微服务·架构
今天也好累6 小时前
C 语言基础第16天:指针补充
java·c语言·数据结构·笔记·学习·算法