实现思路

准备两个队列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;

// 从队列左侧弹出一个元素,如果有值,说明还有剩余库存
$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;
}

redis的所有方法都具有原子性,高并发下,也是一条一条执行的。但是,如果2个方法一起使用的话,则无法保证原子性。所以只能使用list类型的popLeft方法,可以避免高并发下的超卖

最新文章

  1. R语言-处理异常值或报错的三个示例
  2. CSS中LI圆点样式li {list-style-type:符号名称}
  3. Android Tab -- 使用ViewPager、PagerAdapter来实现
  4. ios开发@selector的函数如何传参数/如何传递多个参数
  5. jQuery插件:简易年月日选择器
  6. Asterisk服务安装配置和启动
  7. [HNOI2006]超级英雄Hero
  8. 在远程服务器上完成本地设备的程序烧写和调试(基于vivado ,SDK软件)
  9. 关于Cookie和Session【转载】
  10. XML实例入门2
  11. Implement custom foreach function in C#
  12. java程序调用xfire发布的webService服务(二)
  13. MySQL/MariaDB的锁
  14. python环境下实现OrangePi Zero寄存器访问及GPIO控制
  15. easyUI文本框获得焦点,失去焦点
  16. 三台机器之间root用户ssh互信配置
  17. css的小知识3
  18. php向mariaDB插入数据时乱码问题解决 --- mysqli_set_charset(设置默认字符编码)
  19. 怎样让DBGrid在按住Shift点鼠标的同时能将连续范围的多行选中?
  20. nrf24l01 IRQ一直为高电平

热门文章

  1. InnoDB和MyISAM区别总结
  2. offer(背包问题、DP)
  3. 吴裕雄--天生自然 JAVA开发学习:变量类型
  4. PAT A1133 Splitting A Linked List (25) [链表]
  5. PAT Basic 1020 ⽉饼 (25) [贪⼼算法]
  6. 试验指标|试验单位|均方|随机模型|固定模型|字母标记法|LSR|q检验|LSD|重复值|弥补缺失数据|可加性|平方根转换|对数转换|反正弦转化
  7. MySQL--MySQL 日志
  8. 使用pycharm遇到问题排查过程
  9. office 无法打开xlsx文件的问题
  10. 两种访问接口的方式(get和post)