🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 秒杀场景的简单实现 完整的版的在迁移博客的时候搞丢了。。。。 队列的特性在日常开发中还可以用于流量削锋跟解耦。这里做流量削锋的秒杀抢购场景的简单示例。 ~~~ //监听已抢购的数量 Redis::watch("sk:1:num"); //已经秒杀完的商品数量 $skNum = Redis::hget("sk:h:1",'gum'); //秒杀商品Hash信息 $isSkNum = (int)Redis::get("sk:1:num"); if($isSkNum < $skNum ){ $uid = $this->rand(5);//随机生成用户id // 暂时用setnx 跟 expire 处理限购 问题是并发情况下会不止10个人进来,但是不影响限购啊 // 没有考虑到更好的解决方案,先这么处理吧 // Redis::set("sk:su:1", 1 , 'NX', 'EX', "1000"); 不清楚predis下set 同时设置 NX和EX为什么老是不生效,暂时用下边的方法处理 if(Redis::setnx("sk:su:".$uid,$uid)){ Redis::expire("sk:su:".$uid,10); //设置过期时间,保证10秒内一个用户只能秒杀成功一次 }else{ Rddis::incr('fail'); echo "10秒内允许抢购一次。"; } //上述代码不能放在multi之内。 否则if(Redis::setnx("sk:su:".$uid,$uid)) 会报错 //放在multi当中,相当于未执行,结果不会返回,所以会一直报错 Redis::multi(); Redis::incr('sk:1:num'); Redis::lpush("sk:l:1",$uid); Redis::exec(); }else{ Redis::incr('fail'); echo "不好意思,秒杀已经结束了。"; } ~~~ * * * ab 1000请求 100并发的请求结果: ~~~ 127.0.0.1:6379> get sk:1:num "10" 127.0.0.1:6379> lrange sk:l:1 0 -1 1) "t106A0502910239" 2) "160A50HR21k23R9" 3) "160i7O502f12Y39" 4) "160j5021W23UzZ9" 5) "Wd160c5i0212539" 6) "1Pw60I502Ae1239" 7) "146050RgG213239" 8) "1605p0aL212p3u9" 9) "16050wyAa2123Y9" 10) "16050fi2012f3j9" ~~~