用户下单链路:
商品列表→详情→具体的项目→结算补充下单信息→下单
商品的信息可以放进缓存
无锁方案
-
调用用户信息服务
-
获取商品信息
-
校验
- 限购和一些别的基础校验
-
开启事务,库存锁定
-
落库
问题
- 大事务下事物阻塞——DB连接池耗尽
- 单行库存热点——-行锁竞争引发死锁
修改库存和落单时间上冲突?
异步下单
”用户获取下单Token,轮询查询结果(平均等待5-8秒)
在下单的时候,返回前端一个token。
然后将这个操作放进redis队列中
等待定时任务进行轮训操作,并将结果返回
优点:
-
合并写,数据库压力小了
- 每次都可以获取个几十条信息,同时更新mysql
redis扣减
问题
支付过后,还有回调,可能也会有压力
在之前的异步下单链路中还是存在几个问题
- 前端用户体验,前端轮询下单结果,会有一个较长时间的等待。
- 支付回调流量不可把控,如果支付回调QPS过高,也会导致库存单行扣减压力
- 整个流程都是串行处理,如果下游接口响应耗时过高,会导致服务雪崩问题。
所以还需要对下单链路进行处理
- 库存单行扣减优化
- 接口部分调用串行转成并行处理,降低接口响应耗时,提升服务处理速度
方案
- redis+lua库存扣减
- DB兜底(10%库存):故障熔断时启用,结合库存校准机制防超卖(日志回溯+定时校准)。
支付回调:
- 写进临时表,定时任务统一处理
Redis扣减失败会通过数据库进行扣减,失败达到阈值触发库存校准,并关闭热点标。
也就是说redis扣减失败过多之后,将库存返还给mysql
那这样mysql的压力不是很大了?
别的操作
缓存预热,限流,降级