抢购,秒杀是我们常见的一个应用场景,主要需要解决的两个问题,一个是高并发对数据库产生的压力,另一个是正确的减少库存的问题,即超卖问题。
下面是我总结的几种方案:
优化方案一:将库存字段number字段设为unsigned,当库存为0时,因为字段不能为负数,将会返回false。
优化方案二:使用mysql的事物锁,锁住要操作的行。
优化方案三:使用非堵塞的文件排它锁
优化方案四:使用redis队列,因为POP操作是原子的即使有很多用户同时到达,也是依次执行。
当然真实的秒杀场景没有说的这么简单,比这复杂的多,有很多需要注意的地方,比如抢购页面做成静态页,通过ajax调用接口。
还有一种场景,可能会出现一个用户抢多个秒杀商品的结果,这时候我们就需要一个排队队列,一个抢购结果队列,以及一个库存队列,循环处理从排队队列中取出一个用户,判断用户是否已经在抢购结构队列里面,相当于一个过滤,如果已经在结果队列里面,则表示已抢购,反之,表示未抢购,库存减1。
建议:
1.秒杀这种活动不会经常出现,可以使用一台专门的服务器只做秒杀。
2.Mysql事物在高并发下,性能下降很厉害,文件锁的方式也是如此,推荐使用redis队列来实现。
还有一种场景,可能会出现一个用户抢多个秒杀商品的结果,这时候我们就需要一个排队队列,一个抢购结果队列,以及一个库存队列,循环处理从排队队列中取出一个用户,判断用户是否已经在抢购结构队列里面,相当于一个过滤,如果已经在结果队列里面,则表示已抢购,反之,表示未抢购,库存减1。
建议:
1.秒杀这种活动不会经常出现,可以使用一台专门的服务器只做秒杀。
2.Mysql事物在高并发下,性能下降很厉害,文件锁的方式也是如此,推荐使用redis队列来实现。