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;

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

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

秒杀结果

php结合Redis实现高并发下的秒杀抢购功能_第1张图片

    从截图上可以看出,正好符合我们的预期,秒杀基本完成,剩下的就是一些后续的业务逻辑处理,如:入库操作等等。

 

 

你可能感兴趣的:(Redis)