前言: 商城系统最有看点的当属秒杀商品了,处理高并发需要根据业务的不同而选择不同的处理方法,此文章仅代表鄙人的总结和理解,如有错漏,欢迎指正...
一、秒杀的特点
抢的人多(请求的多),商品却少(可以限制请求量)
二、设计秒杀需要考虑的东西
1、保存某个用户的秒杀资格
答:普通做法是在用户表中添加资格列,弊端就是每次都要查询,字段又多。----》解决办法就是:新建一张表,userid为主键,并新增几个字段即可,查询速度也会上来,数据量也不会很多。
2、显示商品的详情的内容
答:由于需要的信息种类多,涉及的表不同,需要搜索很多张表,影响效率。---》解决办法就是不要一开始就把所有数据返回给前端,当用户点击的时候再请求新的动态数据。
3、秒杀活动开抢的处理
答:缓存静态页面,缓存url,活动开始前事先发起必要的数据,尽量减少任何对数据库的不必要操作,留出足够的并发量给数据库。
4、秒杀请求是一个秒杀系统能不能抗住高并发的关键,因为请求不能缓存
分析:秒杀请求主要是两个请求:1.扣库存 2.发送秒杀商品 ,这两个都需要对数据库进行update和select操作,当请求量过大的时候将会造成拥堵,即使0.5S的时间页面没有显示已经抢完,还是会有上万的请求发送过来
三、解决方法
1、第一步就是要限制秒杀人数。比如有1000个名额,要保证商品被完全抢光就限制1500个请求名额,当用户点击进去抢购的页面之后,页面要保存已经进入的用户id,当抢购完成后,使用redis的set保存人数,避免重复请求产生错误的库存。
2、二次优化:分库存,当商品数量成千上万的时候,redis分库存,每个redis分配等量的库存数量,请求页面随机进入不同的redis减库存,不用担心某个redis会出现没抢光的情况,因为是高并发,所以用户是感知不到的。
3、三次优化:扣库存和发货的信息,使用异步通知。使用消息系统进行异步通信。比如抢购成功了,就异步发送短信给手机,而不是返回某个东西,节省时间
四、抢购、秒杀防止超卖的方式
解决库存超卖问题解决方案有:
1.悲观锁
2.分布式锁(redis分布式锁、zk分布式锁、数据库分布式锁)
3.乐观锁
1、单机使用version 乐观锁(简单易用)
所谓乐观锁与前边最大区别在于基于CAS思想,是不具有互斥性,不会产生锁等待而消耗资源,操作过程中认为不存在并发冲突,只有update version失败后才能觉察到。我们的抢购、秒杀就是用了这种实现以防止超卖。
通过增加递增的版本号字段实现乐观锁
select ...,version
update table set version+1 where version=xx

2、分布式使用redis分布式锁
详情请参考博客 --》 使用Redis分布式锁处理并发,解决超卖问题
3、分布式锁可以解决库存超卖的问题,但是无法解决高并发下的性能问题
使用分段加锁的方式解决
假如你现在iphone有1000个库存,那么你完全可以给拆成20个库存段,要是你愿意,可以在数据库的表里建20个库存字段,比如stock_01,stock_02,类似这样的,也可以在redis之类的地方放20个库存key。
总之,就是把你的1000件库存给他拆开,每个库存段是50件库存,比如stock_01对应50件库存,stock_02对应50件库存。
接着,每秒1000个请求过来了,好!此时其实可以是自己写一个简单的随机算法,每个请求都是随机在20个分段库存里,选择一个进行加锁。
bingo!这样就好了,同时可以有最多20个下单请求一起执行,每个下单请求锁了一个库存分段,然后在业务逻辑里面,就对数据库或者是Redis中的那个分段库存进行操作即可,包括查库存 -> 判断库存是否充足 -> 扣减库存。
这相当于什么呢?相当于一个20毫秒,可以并发处理掉20个下单请求,那么1秒,也就可以依次处理掉20 * 50 = 1000个对iphone的下单请求了。
一旦对某个数据做了分段处理之后,有一个坑大家一定要注意:就是如果某个下单请求,咔嚓加锁,然后发现这个分段库存里的库存不足了,此时咋办?
这时你得自动释放锁,然后立马换下一个分段库存,再次尝试加锁后尝试处理。这个过程一定要实现。
分布式锁并发优化方案有没有什么不足?
不足肯定是有的,最大的不足,大家发现没有,很不方便啊!实现太复杂了。
首先,你得对一个数据分段存储,一个库存字段本来好好的,现在要分为20个分段库存字段;
其次,你在每次处理库存的时候,还得自己写随机算法,随机挑选一个分段来处理;
最后,如果某个分段中的数据不足了,你还得自动切换到下一个分段数据去处理
这个过程都是要手动写代码实现的,还是有点工作量,挺麻烦的。
不过我们确实在一些业务场景里,因为用到了分布式锁,然后又必须要进行锁并发的优化,又进一步用到了分段加锁的技术方案,效果当然是很好的了,一下子并发性能可以增长几十倍。
详情请参考博客 --》 如何对分布式锁进行高并发优化
结语:以往都是看别人的博客进行学习技术,其中不乏有精华博客也有吊儿郎当的CV大法文章,所以决定将自己所学所用所整理的知识分享给大家,主要还是想为了后浪们少走些弯路,多些正能量的博客,如有错漏,欢迎指正,仅希望大家能在我的博客中学到知识,解决到问题,那么就足够了。谢谢大家!(转载请注明原文出处)