1.1测试代码
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$userkey = "sk" . $_GET['product_id'] . 'user';
$kckey = "sk" . $_GET['product_id'] . 'qc';
$uid = rand(100000000, 999999999);
//乐观锁
$redis->watch($kckey);
//获取
$kc = $redis->get($kckey);
if ($kc == null) {
echo "秒杀还没开始,请等待";
$redis->close();
return false;
}
//判断用户是否已经秒杀过了
if ($redis->sIsMember($userkey, $uid)) {
echo "已经秒杀过了。不可以重复秒杀";
$redis->close();
return false;
}
if ((int)$kc <= 0) {
echo "秒杀已经结束了";
$redis->close();
return false;
}
$multi = $redis->multi();
$multi->decr($kckey);
$multi->sAdd($userkey, $uid);
$result = $multi->exec();
if ($result == null || count($results) == 0) {
echo "秒杀失败了";
$redis->close();
return false;
}
echo "成功";
$redis->close();
1.2 开始测试
//连接redis
vagrant@homestead:~$ redis-cli
//写入库存
set sk1qc 2000
//使用ab压测
ab -n 3000 -c 300 网站地址?product_id=1
//执行
127.0.0.1:6379> get sk1qc
"928"
2.1.使用lua脚本解决乐观锁库存遗留问题
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$uid = rand(100000000, 999999999);
$lua = <<<'LUA'
local userid = KEYS[1];
local prodid = KEYS[2];
local qtkey = "sk"..prodid.."qc";
local userskey = "sk"..prodid.."user";
local userExists = redis.call("sismember", userskey, userid);
if tonumber(userExists) == 1 then
return 2
end
local number = redis.call("get", qtkey);
if tonumber(number) <= 0 then
return 0
else
redis.call("decr", qtkey);
redis.call("sadd", userskey, userid);
end
return 1;
LUA;
$s = $redis->eval($lua, [$uid, $_GET['product_id']], 2);
var_dump($s);
2.2 开始测试
//连接redis
vagrant@homestead:~$ redis-cli
//写入库存
set sk1qc 2000
//使用ab压测
ab -n 3000 -c 300 网站地址?product_id=1
//执行完成后发现库存还有遗留
127.0.0.1:6379> get sk1qc
"0"