php redis实现秒杀功能
博客专区 > RitaChen 的博客 > 博客详情
php redis实现秒杀功能
RitaChen 发表于1年前
php redis实现秒杀功能
  • 发表于 1年前
  • 阅读 191
  • 收藏 0
  • 点赞 0
  • 评论 0

【腾讯云】新注册用户域名抢购1元起>>>   

主要针对并发情况下,通过redis的分布式锁和队列的方式进行处理的代码

Queue:{商品ID}:   数据类型是有序集合(zset),成员是用户ID,score是用户入队的时间戳

Lock:Queue:{商品ID}: 数据类型是字符串(string),存储的是该锁的过期时间

goods:{商品ID}:stock: 存储的是商品的库存数量

简单介绍demo代码中的实现思路:

将当前秒杀的商品id作为一个队列名称

$queue_name = “Queue:{商品ID}”;

对$queue_name进行加锁

    通过setnx(满足原子性)实现加锁  :$redis->setnx("Lock:Queue:{商品ID}",  $expire time)

    加锁成功,给该锁设置一个过期时间,主要是为了防止死锁

    如果加锁失败,通过设置休眠时间,进行循环请求

加锁成功后,判断队列中的成员数是否超过指定的大小

$count = $this->redis->zCard("Queue:{$name}");
if($count >=  $this->redis->get("goods:{$name}:stock")) {
    $this->lockModel->unlock("Queue:$name");
    return '超过指定集合数量';
}

 判断用户ID是否存在队列中,如不存在则加入队列(score:存入的是当前时间戳 )

if (false === $this->redis->zScore("Queue:$name", $user_id)) {
    $this->redis->zAdd("Queue:$name", $score, $user_id);
}

入队成功,进行解锁$redis->del("Lock:Queue:{商品ID}");提示用户抢购成功。成功的用户会跳转到确认购买的页面,点击确认后才会生成订单、出队等后续操作

ps: 针对多个账号,一次性发送多个请求可以通过ip的访问频率的限制来预防

参考文章:http://blog.jobbole.com/95156/

demo代码的下载地址:https://github.com/Ritajiajia/redis_test/tree/master/test/seckill

    

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 3
博文 11
码字总数 20172
×
RitaChen
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: