码迷,mamicode.com
首页 > 其他好文 > 详细

redis实现高并发下的抢购/秒杀功能

时间:2018-01-05 01:15:12      阅读:549      评论:0      收藏:0      [点我收藏+]

标签:工具   分析   定义   div   use   导致   并发   库存   https   

1, http://www.cnblogs.com/phpper/p/6716248.html

https://www.cnblogs.com/phpper/p/7085663.html

https://www.cnblogs.com/TankXiao/p/4045439.html

之前写过一篇文章,高并发的解决思路(点此进入查看),今天再次抽空整理下实际场景中的具体代码逻辑实现吧:
抢购/秒杀是如今很常见的一个应用场景,那么高并发竞争下如何解决超抢(或超卖库存不足为负数的问题)呢?

常规写法:

查询出对应商品的库存,看是否大于0,然后执行生成订单等操作,但是在判断库存是否大于0处,如果在高并发下就会有问题,导致库存量出现负数

这里我就只谈redis的解决方案吧...
我们先来看以下代码(这里我以laravel为例吧)是否能正确解决超抢/卖的问题:

<?php

  $num = 10; //系统库存量
  $user_id = \Session::get(‘user_id‘);//当前抢购用户id
  $len = \Redis::llen(‘order:1‘); //检查库存,order:1 定义为健名
  if($len >= $num)
    return ‘已经抢光了哦‘;

  $result = \Redis::lpush(‘order:1‘,$user_id); //把抢到的用户存入到列表中
  if($result)
    return ‘恭喜您!抢到了哦‘;

?>

如果代码正常运行,按照预期理解的是列表order:1中最多只能存储10个用户的id,因为库存只有10个。
然而,但是,在使用jmeter工具模拟多用户并发请求时,最后发现order:1中总是超过5个用户,也就是出现了“超抢/超卖”。
分析问题就出在这一段代码:

 $len = \Redis::llen(‘order:1‘);  //检查库存,order:1 定义为健名
 if($len >= $num)
   return ‘已经抢光了哦‘;



在抢购进行到一定程度,假如现在已经有9个人抢购成功,又来了3个用户同时抢购,这时if条件将会被绕过(条件同时被满足了),
这三个用户都能抢购成功。而实际上只剩下一件库存可以抢了。
在高并发下,很多看似不大可能是问题的,都成了实际产生的问题了。要解决“超抢/超卖”的问题,
核心在于保证检查库存时的操作是依次执行的,再形象的说就是把“多线程”转成“单线程”。
即使有很多用户同时到达,也是一个个检查并给与抢购资格,一旦库存抢尽,后面的用户就无法继续了。

redis实现高并发下的抢购/秒杀功能

标签:工具   分析   定义   div   use   导致   并发   库存   https   

原文地址:https://www.cnblogs.com/maomaochong123/p/8196721.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!