b站抢票文章阅读(秒杀)

0 阅读2分钟

用户下单链路:

商品列表→详情→具体的项目→结算补充下单信息→下单

商品的信息可以放进缓存

无锁方案

image.png

  1. 调用用户信息服务

  2. 获取商品信息

  3. 校验

    1. 限购和一些别的基础校验
  4. 开启事务,库存锁定

  5. 落库

问题

  • 大事务下事物阻塞——DB连接池耗尽
  • 单行库存热点——-行锁竞争引发死锁

修改库存和落单时间上冲突?

异步下单

”用户获取下单Token,轮询查询结果(平均等待5-8秒)

在下单的时候,返回前端一个token。

然后将这个操作放进redis队列中

等待定时任务进行轮训操作,并将结果返回

优点:

  • 合并写,数据库压力小了

    • 每次都可以获取个几十条信息,同时更新mysql

redis扣减

问题

支付过后,还有回调,可能也会有压力

在之前的异步下单链路中还是存在几个问题

  1. 前端用户体验,前端轮询下单结果,会有一个较长时间的等待。
  2. 支付回调流量不可把控,如果支付回调QPS过高,也会导致库存单行扣减压力
  3. 整个流程都是串行处理,如果下游接口响应耗时过高,会导致服务雪崩问题。

所以还需要对下单链路进行处理

  1. 库存单行扣减优化
  2. 接口部分调用串行转成并行处理,降低接口响应耗时,提升服务处理速度

方案

  • redis+lua库存扣减
  • DB兜底(10%库存):故障熔断时启用,结合库存校准机制防超卖(日志回溯+定时校准)。

支付回调:

  • 写进临时表,定时任务统一处理
💡

Redis扣减失败会通过数据库进行扣减,失败达到阈值触发库存校准,并关闭热点标。

image.png

也就是说redis扣减失败过多之后,将库存返还给mysql

那这样mysql的压力不是很大了?

别的操作

缓存预热,限流,降级