php结合Redis实现高并发下的秒杀抢购功能
实现思路
准备两个队列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方法,可以避免高并发下的超卖
最新文章
- R语言-处理异常值或报错的三个示例
- CSS中LI圆点样式li {list-style-type:符号名称}
- Android Tab -- 使用ViewPager、PagerAdapter来实现
- ios开发@selector的函数如何传参数/如何传递多个参数
- jQuery插件:简易年月日选择器
- Asterisk服务安装配置和启动
- [HNOI2006]超级英雄Hero
- 在远程服务器上完成本地设备的程序烧写和调试(基于vivado ,SDK软件)
- 关于Cookie和Session【转载】
- XML实例入门2
- Implement custom foreach function in C#
- java程序调用xfire发布的webService服务(二)
- MySQL/MariaDB的锁
- python环境下实现OrangePi Zero寄存器访问及GPIO控制
- easyUI文本框获得焦点,失去焦点
- 三台机器之间root用户ssh互信配置
- css的小知识3
- php向mariaDB插入数据时乱码问题解决 --- mysqli_set_charset(设置默认字符编码)
- 怎样让DBGrid在按住Shift点鼠标的同时能将连续范围的多行选中?
- nrf24l01 IRQ一直为高电平
热门文章
- InnoDB和MyISAM区别总结
- offer(背包问题、DP)
- 吴裕雄--天生自然 JAVA开发学习:变量类型
- PAT A1133 Splitting A Linked List (25) [链表]
- PAT Basic 1020 ⽉饼 (25) [贪⼼算法]
- 试验指标|试验单位|均方|随机模型|固定模型|字母标记法|LSR|q检验|LSD|重复值|弥补缺失数据|可加性|平方根转换|对数转换|反正弦转化
- MySQL--MySQL 日志
- 使用pycharm遇到问题排查过程
- office 无法打开xlsx文件的问题
- 两种访问接口的方式(get和post)