秒杀系统
Posted 猿媛之家
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了秒杀系统相关的知识,希望对你有一定的参考价值。
在谈及高并发、高可用、高性能的技术时,秒杀是老生常谈的话题,本文会利用最小的篇幅把秒杀涉及的技术描述出来。
一、技术架构
秒杀通常有两种限制:库存限制、时间限制。秒杀技术实现核心思想是运用缓存减少数据库瞬间的访问压力。读取商品详细信息时运用缓存,当用户点击抢购时减少缓存中的库存数量,当库存数为0或活动期结束时,同步到数据库。产生的秒杀预订单也不会立刻写到数据库中,而是先写到缓存,当用户付款成功后再写入数据库。
1.秒杀商品存入缓存
秒杀商品由商家在管理后台存入mysql,设置定时任务,每隔一段时间就从Mysql中将符合条件的数据从Mysql中查询出来并存入缓存中,redis以Hash类型进行数据存储。
2.用户下单
用户在下单的时候,需要基于JWT令牌信息进行登陆人信息认证,确定当前订单是属于谁的。并且为了提升下单速度,可以将订单数据存储redis中,如果用户支付成功,则将redis中的订单数据存入Mysql中,并清空redis中的订单数据。
二、秒杀系统的设计和技术方案
1.秒杀考虑的问题
超卖问题
高并发
接口防刷
秒杀URL
数据库设计
大量请求问题
2.秒杀系统数据库设计
seckill_order秒杀订单表:
--order_id订单id;
--user_id用户id;
--goods_id商品id;
--state支付状态,用1代表已支付,0代表未支付;
--create_time订单创建时间;
seckill_goods秒杀货物表:
--id自增id;
--goods_id货物id;
--goods_name商品名;
--stock库存;
--start_time秒杀活动开始时间;
--end_time秒杀活动结束时间;
3.秒杀URL的设计
为了避免有程序访问经验的人通过下单页面url直接访问后台接口来秒杀货品,我们需要将秒杀url实现动态化,即使是开发整个系统的人都无法在秒杀开始前知道秒杀的url。具体的做法就是通过md5加密一串随机字符作为秒杀的url,然后前端访问后台获取具体的url,后台校验通过之后才会继续秒杀。
4.redis预减库存
很多请求进来,都需要后台查询库存,这是一个频繁读的场景。可以使用redis来预减库存,在秒杀开始前可以在redis设值,比如redis.set(goodsld,100),这里预放的库存为100可以设置为常量。每次下单成功之后,Integer stock=(Integer)redis.get(goodsld),然后判断stock的值,如果小于常量值就减去1;不过注意当取消的时候,需要增加库存,增加库存的时候也得注意不能大于之前设定的总库存数(查询库存和扣减库存需要原子操作,此时可以借助lua脚本)下次下单再获取库存的时候,直接从redis里面查就可以了。
以上是关于秒杀系统的主要内容,如果未能解决你的问题,请参考以下文章