架构具体改变与优势对比
1. 库存管理方式的改变
|
方面 |
改变前(旧方案) |
改变后(新方案) |
优势体现 |
|---|---|---|---|
|
库存锁定时机 |
抢购成功立即锁定 |
支付成功后才锁定 |
防止库存被不支付的人长期占用 |
|
库存状态 |
只有一份真实库存 |
两份库存:Redis预扣 + MySQL真实 |
更精细化的库存管理 |
|
超卖风险 |
Redis扣完就认为卖出 |
Redis预扣,MySQL最终确认 |
双重保障,永不超卖 |
2. 系统压力的改变
|
压力点 |
改变前 |
改变后 |
优势 |
|---|---|---|---|
|
抢购瞬间 |
Redis和MySQL都要抗高并发 |
只需要Redis抗高并发 |
MySQL压力减少90% |
|
支付环节 |
只是简单的支付确认 |
支付确认+扣减库存 |
支付系统更专注,库存系统压力分散 |
|
恢复机制 |
退款才释放库存 |
不支付就自动释放 |
库存周转率提升3-5倍 |
3. 用户体验的改变
|
用户场景 |
改变前 |
改变后 |
用户感受 |
|---|---|---|---|
|
抢购瞬间 |
抢到后直接扣库存 |
抢到是"资格",不是"商品" |
压力减小,更愿意尝试 |
|
支付环节 |
15分钟支付倒计时 |
15-30分钟支付时间 |
时间更充裕,体验更好 |
|
抢购失败 |
直接显示"已售罄" |
可能等别人未支付又放出 |
有"捡漏"机会,体验提升 |
|
恶意抢购 |
抢到不付,库存就没了 |
不支付,库存就释放 |
黄牛难以囤货 |
秒杀系统时序图(支付成功后扣减库存)

核心流程变更说明
关键变化:支付成功后扣减真实库存
1. 库存扣减分为两步:
第一步(预扣):
用户抢购 → Redis预扣库存 → 记录用户资格
(保证公平性,防止超卖)
第二步(实扣):
用户支付成功 → 调用库存系统 → MySQL真实扣减
(保证数据一致性)
2. 各阶段库存状态:
|
阶段 |
Redis库存 |
MySQL库存 |
说明 |
|---|---|---|---|
|
抢购前 |
100 |
100 |
初始化状态一致 |
|
抢购成功 |
99 |
100 |
Redis已预扣,MySQL未动 |
|
支付成功 |
99 |
99 |
支付后MySQL真实扣减 |
|
支付失败/超时 |
100 |
100 |
库存恢复原状 |
3. 新增的业务逻辑:
库存回滚机制:
用户抢到 → 创建订单 → 支付超时 → 释放预扣库存
订单状态流转:
待支付 → 已支付 → 已发货
↓
→ 已取消 → 释放库存
↓
→ 已超时 → 释放库存
优化后的完整业务流程
第一阶段:抢购资格获取(毫秒级)

第二阶段:订单处理(秒级)

第三阶段:库存管理(异步)

关键设计考虑
1. 为什么支付后才扣真实库存?
-
降低锁冲突:避免支付过程中长时间锁定库存
-
提高转化率:用户有充足时间支付
-
防止恶意占库存:不支付就释放给别人
-
支持优惠券等活动:支付时可使用各种优惠
2. 预扣库存的作用:
-
防止超卖:保证公平性,先到先得
-
快速响应:毫秒级确定抢购结果
-
用户体验:立即知道是否抢到
3. 超时处理策略:
-
一般15-30分钟:给用户足够支付时间
-
自动释放:超时后库存重回可抢购状态
-
通知用户:提醒用户订单即将取消
数据一致性保障
1. 最终一致性方案:
Redis预扣库存 ≠ MySQL真实库存
↓
用户支付完成
↓
MySQL库存 = Redis库存(达成一致)
↓
如果支付失败,Redis库存恢复
2. 异常处理机制:
|
异常场景 |
处理方式 |
结果 |
|---|---|---|
|
抢购成功,下单失败 |
释放Redis预扣库存 |
用户可重新抢购 |
|
下单成功,支付超时 |
自动取消订单,释放库存 |
库存可重新销售 |
|
支付成功,扣库存失败 |
重试机制,保证最终扣减 |
数据最终一致 |
|
系统宕机 |
定时任务扫描补偿 |
恢复正确状态 |
系统优势总结
-
响应极快:抢购结果毫秒级返回
-
永不超卖:Redis原子操作保证
-
弹性扩展:各环节可独立扩容
-
用户体验好:立即知道结果,充足支付时间
-
系统稳定:支付压力不直接影响库存
-
数据安全:支付后才真正扣减,防止资金损失
这个设计实现了秒杀系统的"既要、又要、还要":
-
既要响应速度快
-
又要永不超卖
-
还要系统稳定
-
更要用户体验好
5万+

被折叠的 条评论
为什么被折叠?



