• php结合Redis实现高并发下的秒杀抢购功能


    实现思路

        准备两个队列A和B,假设A队列的名称为stock,用于存放商品总库存信息,B队列的名称为users,用于存放抢购成功后的用户信息。每当有用户进行抢购操作时,先从A队列弹出一个元素,如果该元素有值,说明还有剩余库存,此时,将用户信息存入B队列,否则,说明已无库存,应该终止抢购。

    代码部分

        stock.php 用于设置队列中的库存信息


    // 秒杀开始前,将库存放入redis队列中

    include_once dirname(__FILE__) . '/RedisUtil.php';

    $config = array(
    'host' => '127.0.0.1', // redis 服务器地址
    'port' => 10001, // redis 服务器端口号
    'timeOut' => 10, // redis 客户端连接超时时间
    'password' => '123456' // redis 客户端连接密码
    );
    $redisUtil = new RedisUtil($config);

    // 假设秒杀总库存为500
    $stock = 500;

    // 待秒杀的商品编号
    $goodsId = 1000001;

    // 将商品库存依次放入队列中
    for ($i=0; $i<$stock; $i++) {
    $redisUtil->setLeftList('stock_'.$goodsId,1);
    }
        buy.php 模拟秒杀抢购


    // 模拟秒杀

    include_once dirname(__FILE__) . '/RedisUtil.php';

    $config = array(
    'host' => '127.0.0.1', // redis 服务器地址
    'port' => 10001, // redis 服务器端口号
    'timeOut' => 10, // redis 客户端连接超时时间
    'password' => '123456' // redis 客户端连接密码
    );
    $redisUtil = new RedisUtil($config);

    // 此处假设有10000个用户同时来抢购商品,注意:我们的库存只有500个
    // 预期情况是:500个库存都被抢光,且没有出现超卖现象

    $users = 10000;

    // 待秒杀的商品编号
    $goodsId = 1000001;


    // 从队列左侧弹出一个元素,如果有值,说明还有剩余库存
    $rs = $redisUtil->popLeft('stock_'.$goodsId);
    $num = sprintf('%05s', $i);
    if (!$rs) {
    echo '售罄了!用户'.$num;
    echo '<br/>';
    // 输出最终抢购成功的用户数量
    echo '最终抢购人数:'.$redisUtil->getListSize('users').' 人';
    echo '<br/>';
    echo '<br/>';
    return;
    } else {
    // 将抢购成功的用户存入队列
    $redisUtil->setLeftList('users',$num);
    echo '恭喜您!用户'.$num;
    }

    redis的所有方法都具有原子性,高并发下,也是一条一条执行的。但是,如果2个方法一起使用的话,则无法保证原子性。所以只能使用list类型的popLeft方法,可以避免高并发下的超卖

  • 相关阅读:
    伺服电机常见故障分析汇总
    PLC常见四大故障及其处理方法
    Qt QString的arg()方法的使用
    Qt 线程池QThreadPool类、QRunnable类
    C++线程池的实现
    C++ List的用法
    C++语言堆栈的详细讲解
    QT中的QQueue类、C++中的queue类
    Qt platform plugin 'windows' 问题的解决方法
    电气接地的相关介绍
  • 原文地址:https://www.cnblogs.com/lansetiankongblog/p/10932146.html
Copyright © 2020-2023  润新知