如果从面试和实际项目角度讲,一个完整的电商下单链路涉及:

商品浏览
   ↓
加入购物车
   ↓
提交订单
   ↓
锁库存
   ↓
创建订单
   ↓
支付
   ↓
扣减库存
   ↓
发货
   ↓
确认收货
   ↓
完成订单

真正复杂的是提交订单到支付成功这一段。


一、整体架构

用户
 ↓
网关 Gateway
 ↓
订单服务 Order
 ↓
商品服务 Product
 ↓
库存服务 Stock
 ↓
优惠券服务 Coupon
 ↓
支付服务 Pay
 ↓
物流服务 Logistics
 ↓
消息队列 MQ

二、提交订单

用户点击:

立即购买

或者

购物车结算

前端提交:

{
  "userId":10001,
  "addressId":1,
  "items":[
    {
      "skuId":1001,
      "count":2
    }
  ]
}

三、防重复提交

很多用户会:

疯狂点击提交订单

可能生成多个订单。

通常生成:

orderToken

例如:

确认页
 ↓
Redis生成token
 ↓
返回前端

提交时:

token校验

利用 Redis:

SETNX

保证只能提交一次。


四、校验商品

订单服务调用商品服务:

skuId=1001

获取:

{
   "price":3999,
   "status":"ON_SALE"
}

检查:

商品是否存在
是否下架
是否删除

五、价格校验

不能相信前端价格。

前端:

{
   "price":1
}

可能被篡改。

必须:

订单服务
 ↓
商品服务查询最新价格
 ↓
重新计算

例如:

3999 × 2 = 7998

六、优惠券校验

调用优惠券服务:

优惠券是否存在
是否过期
是否已使用
是否满足门槛

例如:

满500减50

计算:

7998
-
50
=
7948

七、库存校验

调用库存服务:

sku=1001
count=2

查询:

库存=100

库存足够:

继续

库存不足:

下单失败

八、锁库存(重点)

这里最容易出问题。

假设:

库存=1

用户A:

买1件

用户B:

买1件

同时提交。

如果只是查询:

库存>0

两个人都通过。

结果:

超卖

正确做法:

查询库存
+
锁库存

必须原子操作。

例如:

update stock
set locked = locked + 1
where sku_id = 1001
and stock - locked >=1;

返回:

影响行数=1

说明锁成功。


库存表:

stock
-------------------
sku_id
stock
locked

例如:

stock=100
locked=20

可售:

80

九、创建订单

此时:

库存已经锁住

创建订单:

order

状态:

NEW
待支付

例如:

订单号:
202606090001

写入:

order_item

记录商品明细。


十、发送延迟消息

创建订单后:

支付超时怎么办?

例如:

30分钟未支付

需要自动取消。

发送 MQ:

order.create

延迟:

30分钟

例如:

RocketMQ DelayMessage

十一、用户支付

用户跳转支付:

支付宝
微信支付
银行卡

支付服务生成:

支付单

状态:

UNPAID

十二、第三方回调

支付成功:

支付宝
 ↓
回调支付服务

例如:

{
  "orderNo":"202606090001",
  "tradeStatus":"SUCCESS"
}

支付服务更新

支付成功

发送MQ:

pay.success

十三、订单状态更新

订单服务消费:

pay.success

修改订单:

NEW
 ↓
PAID

十四、真正扣减库存

这是很多面试官爱问的。

为什么不下单就扣库存?

因为:

大量订单不付款

会浪费库存。

因此:

下单
 ↓
锁库存

支付成功:

锁库存
 ↓
正式扣减库存

例如:

stock -= 2
locked -= 2

十五、通知仓库发货

库存服务发送:

stock.deduct.success

订单服务消费:

订单已支付

通知仓储系统:

warehouse.ship

十六、发货

仓库:

出库
打印面单
发货

物流服务:

生成运单号

例如:

SF123456789

订单状态:

PAID
 ↓
DELIVERED

十七、确认收货

用户点击:

确认收货

或者:

7天自动确认

订单状态:

DELIVERED
 ↓
FINISHED

十八、超时未支付怎么处理

延迟消息到达:

order.timeout

订单服务检查:

订单状态

如果:

NEW

说明没付款。

修改:

CANCEL

发送:

stock.unlock

库存服务消费:

stock.unlock

释放库存:

locked -= 2

库存恢复。


十九、高并发场景完整链路

用户
 ↓
提交订单

订单服务
 ↓
校验价格
 ↓
校验优惠券
 ↓
锁库存

库存服务
 ↓
库存锁定成功

订单服务
 ↓
创建订单
 ↓
发送延迟消息

用户支付
 ↓

支付服务
 ↓
支付宝回调

MQ
 ↓

订单服务
 ↓
订单变已支付

库存服务
 ↓
正式扣减库存

仓储服务
 ↓
发货

物流服务
 ↓
更新物流

用户确认收货

订单完成

如果是 Java 面试中被问到「电商下单流程」,比较加分的回答是:

防重Token
→ 商品校验
→ 价格校验
→ 优惠券校验
→ 锁库存
→ 创建订单
→ 延迟消息关单
→ 支付回调
→ MQ通知订单状态变更
→ 扣减库存
→ 发货
→ 自动收货
→ 售后退款

然后重点展开 锁库存、防超卖、支付回调幂等、延迟关单、MQ最终一致性 这几个高频面试点。因为实际生产环境 80% 的复杂度都集中在这几个地方。

Logo

电商企业物流数字化转型必备!快递鸟 API 接口,72 小时快速完成物流系统集成。全流程实战1V1指导,营造开放的API技术生态圈。

更多推荐