最近公司这里要配合支付宝做一个秒杀系统,于是查了相关的资料,
秒杀系统的问题
1)短时间内服务负载高
2)高并发超卖的问题
百度搜索的结果
下面的方法都使用redis即代码
$redis = new \Redis(); if ($redis->connect('127.0.0.1','6379') == false) { die($redis->getLastError()); }
①使用redis的原子性操作,保证不多抢
if($_GET['flag']){ $redis->set('flag',10);exit; } $key_r = $redis->decr('flag');//利用redis的原子性操作,保证不多抢 if ($key_r < 0) { } else { //抢到了 $value="test".rand("1","20"); $redis->zAdd('demo',$redis->get('flag'),$value); $rs=$redis->zRange('demo',0,-1); //print_r($key_r); if(count($rs)+$key_r<10){ $redis->set('flag',$key_r+1); } }
②先把商品放到队列,减队列的方式
if($_GET){ $store=10; $res=$redis->llen('goods_store'); echo $res; $count=$store-$res; for($i=0;$i<$count;$i++){ $redis->lpush('goods_store',1); } $redis->set('flag',10); exit; } $count=$redis->lpop('goods_store'); if(!$count){ insertLog('error:no store redis'); return; }else{ $value="test".rand("1","20"); $redis->zAdd('demo',$redis->get('flag'),$value); }
③慕课网看视频提供的方法
if(!$redis->get('flag')){ $redis->set('flag',1); } $value="test".rand("1","20"); if($redis->get('flag')>10){ }else{ if($redis->zAdd('demo',$redis->get('flag'),$value)){ $redis->incr("flag"); } }
上面的方法都用办法测试过
ab -n 1000 -c 1000 http://127.0.0.1/redis.php
都有问题
②③都出现超卖的情况
① 不会出现超卖会出现少买的情况