Springboot实战——黑马点评之秒杀优化

打印 上一主题 下一主题

主题 868|帖子 868|积分 2614

Springboot实战——黑马点评之 秒杀优化

1 秒杀优化

先来复习以下,秒杀优惠券业务的现有实现逻辑:

以上流程图中的操纵串行执行,效率极低。
其中 判断秒杀库存 以及 校验一人一单 属于对数据库的读取,耗时较少;扣减库存 以及 创建订单 属于对数据库的写操纵,耗时相对较久。
提拔效率的方法我们可以考虑两个方面:
1)引入并发(开启多线程):主线程负责读取操纵,如果读取查验资格通过,则开启另外的线程负责写操纵
2)引入Redis缓存:可以将订单信息以及秒杀券信息存入Redis,在Redis中查验资格后,将符合资格的优惠券id+用户id+订单id存入阻塞队列,单独开启第二线程来读取阻塞队列执行写操纵,即刻给用户返回下单订单号。

1.1 引入Redis进行资格查验

资格查验分为 查抄库存是否充足 以及 用户是否下单过该优惠券 两个操纵,如果引入Redis来实现,要考虑:

  • 秒杀券库存导入Redis,并且要数据及时更新同步,即 在查验资格通过后必要将Redis中的券库存-1

  • 下单记录:使用的数据结构必要满足1 集合;2 元素唯一性
  • 使用Redis中的set范例来缓存下单该优惠券的用户id集合,并且要保证数据及时更新同步,即 在查验资格通过后必要向set中添加用户id



以上所考虑的几点还必要保证操纵的原子性,以是使用Redis的Lua脚本来实现。
Lua脚本必要的ARGV参数列表中有两个待定参数,分别是优惠券id 以及 用户id,其他的业务逻辑均调用Redis命令即可实现
[code]-- 1. 参数列表-- 1.1. 优惠券id 用于查询优惠券库存时的关键字local voucherId = ARGV[1]-- 1.2. 用户id 用于将查询下单用户对比local useId = ARGV[2]-- 2. 数据key-- 2.1. 库存key + 业务前缀 拼接 优惠券idlocal stockKey = 'seckill:stock:' .. voucherId-- 2.2 订单keylocal orderKey = 'seckillrder:' .. voucherId-- 3. 业务执行-- 3.1 起首判断库存是否充足if(tonumber(redis.call('get', stockKey))  斲丧者组以最后一个被获取的消息标识($),读取队列中还没被斲丧的消息,并设置2秒内阻塞式(|block)读取 -> 如果阻塞等待时间内并未拿到最新消息则continue -> 如果阻塞等待时间内获取到新消息,则按下单业务将其处理
捕捉非常 -> 意味着此时pending-list中存在已被斲丧但未被处理完毕的消息 -> 循环从pending-list中获取第0号消息(非阻塞式,0)来尝试继续处理 -> 如果获取到尚未处理过的消息,则按正常下单业务继续处理 -> 如果没有非常停止的消息则结束非常捕捉业务
如果捕捉非常过程中又碰到非常 -> 继续循环读取pending-list</p>
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

篮之新喜

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表