Redis实现高并发下的抢购,秒杀,解决方案
来源:互联网 发布:linux对文件内容排序 编辑:程序博客网 时间:2024/05/10 20:42
在电子商务发达的今天,各种秒杀,抢购活动的场景不少,如何解决高并发下出现的订单超发情况呢?
在常规情况下,我们会根据用户提交的请求去查询商品库存,如果库存小于0则订单生成失败。但是这种情况下经常了订单需要的数量超过了库存数量,即出现负库存。
先讨论常规场景测试:
我们在redis中设置一个库存表,就是个简单的string类型, 用以标示库存即可。
set inventory 100
使用多进程测试如下:因为我的AB测试不能用。所以使用多进程的方式进行
//register a signalpcntl_signal(SIGCHLD, SIG_IGN);$times = 200;while ($times-- > 0) { $pid = pcntl_fork(); if ($pid > 0) { } else { order(); die; }}sleep(20);function order() { $conn = new Redis; //connect redis $conn->connect("127.0.0.1", 6379); $inventory = $conn->get('inventory'); //由于本地服务过访问过快。所以休息50毫秒真实模拟高并发 usleep(50000); if ($inventory > 0) { $conn->decr("inventory"); } else { echo "抢购失败!"; } die;}
执行结果变为了负数:
如何解决这个问题呢? 熟悉redis 的同学都知道 redis 支持事务,我们加个事务试试。
<?php//register a signalpcntl_signal(SIGCHLD, SIG_IGN);$times = 200;while ($times-- > 0) { $pid = pcntl_fork(); if ($pid > 0) { } else { order(); die; }}sleep(20);function order() { $conn = new Redis; //connect redis $conn->connect("127.0.0.1", 6379); $inventory = $conn->get('inventory'); $conn->multi(); //由于本地服务过访问过快。所以休息50毫秒真实模拟高并发 usleep(50000); if ($inventory > 0) { $conn->decr("inventory"); $conn->exec(); } else { echo "抢购失败!"; } die;}?>
同样结果还是会变成负数。
接下来可以使用redis 的watch 实现一个乐观锁来试试
<?php//register a signalpcntl_signal(SIGCHLD, SIG_IGN);$times = 200;while ($times-- > 0) { $pid = pcntl_fork(); if ($pid > 0) { } else { order(); die; }}sleep(20);function order() { $conn = new Redis; //connect redis $conn->connect("127.0.0.1", 6379); do { //watch inventory $conn->watch('inventory'); $inventory = $conn->get('inventory'); //由于本地服务过访问过快。所以休息50毫秒真实模拟高并发 usleep(50000); if ($inventory <= 0) { echo "抢购失败!"; break; } $conn->multi(); $conn->decr("inventory"); } while ($conn->exec()); die;}?>
执行结果:
大致场景就是这样的, 如果是抢购,每次只抢购一个 可以往队列里添加库存个商品的1 队列, 如图:
当用户每次抢购抛出一个队列,然后再去减少真正的库存即可。 当然真实的场景要稍复杂一些, 不过原理就是这样的。
成功!
阅读全文
0 0
- Redis实现高并发下的抢购,秒杀,解决方案
- Redis实现高并发下的抢购、秒杀功能
- Redis实现高并发下的抢购、秒杀功能
- redis实现高并发下的抢购/秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能的实例
- php结合redis实现高并发下的抢购、秒杀功能的实例
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- php结合redis实现高并发下的抢购、秒杀功能
- 浅谈SEO搜索引擎基本工作原理
- mac_jdk安装配置
- 谈下对驾驶证的了解
- MFC下的时间操作
- 使用QT Creator一步一步编写自己的CMake工程
- Redis实现高并发下的抢购,秒杀,解决方案
- Eclipse中的集成Git插件删除线上远程分支
- 关于springMVC+poi上传Excel文件问题解决
- 点击图片放大弹出
- 【金融】四大赛题、中美赛区、明星导师、豪华评委 | JDD大赛报名开启
- 面试题20:顺时针打印矩阵(Leetcode-54和57)
- thinkphp3.2引用ueditor
- javascript 中 alert(1&&2) ==2 问题
- Mysql