使用Redis解决超卖问题

使用ApacheBench模拟高并发,命令及参数如下:
[root@localhost ~]# ab -c 500 -n 500 http://www.domain.com/sell.php



有超卖问题的演示代码

<?php
/**
 * 超卖实验(使用文件保存库存,也可以使用数据库保存库存)
 */
$stockFile = __DIR__ . '/stock.txt';
$stockTotal = 10; // 总库存

/**
 * 获得微秒时间戳(16位数字串)
 *
 * @return int 微秒时间戳(16位数字串)
 */
function us_time()
{
    list($usec, $sec) = explode(' ', microtime());
    return $sec . substr(strval($usec), 2, 6);
}

/**
 * 重置测试环境
 *
 * @return void
 */
function reset_env()
{
    global $stockFile;
    global $stockTotal;

    file_put_contents($stockFile, $stockTotal);

    exit('reset');
}

// reset_env(); // 每次进行实验前记得先重置测试环境

session_start();
$sessionId = session_id();

$ustime = us_time();

$stock = intval(file_get_contents($stockFile)); // 获取库存数
if ($stock >= 1) {
    $stock--; // 库存减1
    file_put_contents($stockFile, $stock);

    $index = $stockTotal - $stock;
    $file = __DIR__ . "/{$ustime}.抢到了(第{$index}个).{$sessionId}.txt";
} else {
    $file = __DIR__ . "/{$ustime}.没抢到.{$sessionId}.txt";
}

file_put_contents($file, '');

/**
 * 实验结果:
 * 出现了超卖现象,且从时间线上看并不是还有库存前面的人就一定会抢到,即可
 * 能出现第1、2、3人抢到,但第4、5人又没抢到的情况。
 */



使用Redis解决超卖问题

<?php
/**
 * 超卖实验(使用Redis保存库存)
 */
$redis = new Redis();
$redis->connect('localhost', 6379);
$redis->auth('密码');

$stockTotal = 10; // 总库存
$redis->setnx('stock', $stockTotal); // 把总库存放入Redis

/**
 * 获得微秒时间戳(16位数字串)
 *
 * @return int 微秒时间戳(16位数字串)
 */
function us_time()
{
    list($usec, $sec) = explode(' ', microtime());
    return $sec . substr(strval($usec), 2, 6);
}

/**
 * 重置测试环境
 *
 * @return void
 */
function reset_env()
{
    global $redis;

    $redis->flushAll();

    exit('reset');
}

// reset_env(); // 每次进行实验前记得先重置测试环境

session_start();
$sessionId = session_id();

$ustime = us_time();

$stock = $redis->decr('stock'); // 库存减1(返回值为自减后的值,提示:最后一个被抢到时返回值为0)
if ($stock >= 0) {
    $index = $stockTotal - $stock;
    $file = __DIR__ . "/{$ustime}.抢到了(第{$index}个).{$sessionId}.txt";
} else {
    $file = __DIR__ . "/{$ustime}.没抢到.{$sessionId}.txt";
}

file_put_contents($file, '');

/**
 * 实验结果:
 * 没有出现超卖现象,且从时间线上看就是前10个用户抢光了10个库存,完美解决了超卖问题。
 */

Copyright © 2024 码农人生. All Rights Reserved