作者:Life一切安好 | 来源:互联网 | 2020-08-16 03:15
本篇文章给大家带来的内容是关于Redis实现秒杀的方法介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
导语:秒杀想必大家都了解,在短时间内请求访问会激增,同时要保证不会超卖和数据的准确,对于技术方面还是有些考验的。可惜的是,一直没有机会在项目中实现。再看了一些资料后,打算实验下。以下代码仅为测试所用,环境比较简单,请根据实际情况进行修改。
创建秒杀队列
在开始秒杀之前,先将商品放入队列中,如下
/**
* 创建秒杀列表
*/
public function createList()
{
$count = 30;
$redisKey = 'goods_list';
for ($i = 1; $i <= $count; $i++) {
// 测试用,防止数据错误
if (Redis::llen($redisKey) >= $count) {
break;
}
Redis::rpush($redisKey, $i);
}
}
执行完后,在 Redis 中看下
有 30 个商品 ID,数据正常。
秒杀
接下来是关键的一步,使用的是 Redis 的 lpop
命令获取商品 ID,利用的是 Redis 的原子性。
/**
* 秒杀
*/
public function buy()
{
// 随机用户名,无意义,仅做标记
$username = Hash::make(now());
if ($goodsId = Redis::lpop(&#39;goods_list&#39;)) {
// 购买成功
Redis::hset(&#39;buy_success&#39;, $goodsId, $username);
} else {
// 购买失败
Redis::incr(&#39;buy_fail&#39;);
}
}
如上,简化了代码,购买之后,成功与否只是做记录。实际应用中,当然会更加复杂,但要注意的是,不要同步操作 Mysql。多说一句,Hash:make(now())
即使值相同,也不会生成相同的数据,参考这里。
测试
最后就是进行测试了,使用 ab 测试,执行 ab -c 300 -n 3000 http://localhost/buy/
,上述命令的意思是 300 并发,共请求 3000 次
好的方面是秒杀成功的数量是准确的,没有超卖。【