准备两个队列A和B,假设A队列的名称为stock,用于存放商品总库存信息,B队列的名称为users,用于存放抢购成功后的用户信息。每当有用户进行抢购操作时,先从A队列弹出一个元素,如果该元素有值,说明还有剩余库存,此时,将用户信息存入B队列,否则,说明已无库存,应该终止抢购。
stock.php 用于设置队列中的库存信息
// 秒杀开始前,将库存放入redis队列中include_once dirname(__FILE__) . '/RedisUtil.php';$config = array('host' => '127.0.0.1', // redis 服务器地址'port' => 10001, // redis 服务器端口号'timeOut' => 10, // redis 客户端连接超时时间'password' => '123456' // redis 客户端连接密码);$redisUtil = new RedisUtil($config);// 假设秒杀总库存为500$stock = 500;// 待秒杀的商品编号$goodsId = 1000001;// 将商品库存依次放入队列中for ($i=0; $i<$stock; $i++) {$redisUtil->setLeftList('stock_'.$goodsId,1);}
buy.php 模拟秒杀抢购
// 模拟秒杀include_once dirname(__FILE__) . '/RedisUtil.php';$config = array('host' => '127.0.0.1', // redis 服务器地址'port' => 10001, // redis 服务器端口号'timeOut' => 10, // redis 客户端连接超时时间'password' => '123456' // redis 客户端连接密码);$redisUtil = new RedisUtil($config);// 此处假设有10000个用户同时来抢购商品,注意:我们的库存只有500个// 预期情况是:500个库存都被抢光,且没有出现超卖现象$users = 10000;// 待秒杀的商品编号$goodsId = 1000001;for ($i=1; $i<=$users; $i++) {// 从队列左侧弹出一个元素,如果有值,说明还有剩余库存$rs = $redisUtil->popLeft('stock_'.$goodsId);$num = sprintf('%05s', $i);if (!$rs) {echo '售罄了!用户'.$num;echo '<br/>';// 输出最终抢购成功的用户数量echo '最终抢购人数:'.$redisUtil->getListSize('users').' 人';echo '<br/>';echo '<br/>';return;} else {// 将抢购成功的用户存入队列$redisUtil->setLeftList('users',$num);echo '恭喜您!用户'.$num;}echo '<br/>';}
此处假设有10000个用户同时来抢购商品,注意:我们的库存只有500个,预期情况是:500个库存都被抢光,且没有出现超卖现象。
秒杀结果

从截图上可以看出,正好符合我们的预期,秒杀基本完成,剩下的就是一些后续的业务逻辑处理,如:入库操作等等。
