PHP高并发实例详解之商品库存超卖并发测试
2789
在之前的文章《PHP高并发实例详解之解决商品库存超卖问题》中,我们讲到了关于在高并发情况下防止商品库存超卖的相关问题,下面我们一起来看一下防止库存超卖之并发测试的相关内容,希望对大家有帮助。
基于《PHP高并发实例详解之解决商品库存超卖问题》的测试案例
一、 普通下单
并发测试时 product 表 id =1 name = 稻花香大米 store = 15
请求总数30 每次10个并发
- ab -n 30 -c 10 http://xxxxx.top/code/the_limit/add_order.php
结果:
有 15 次库存减少成功 store 库存出现了负数 -7 8 次判断为库存不够 (库存负数是不正确的 不允许的)
二、unsigned 模式
调整回 product 表 id =1 name = 稻花香大米 store = 15
请求总数30 每次10个并发
- ab -n 30 -c 10 http://xxxxx.top/code/the_limit/unsigned.php
结果:
有 15 次库存减少成功 store 库存出现了负数 -6 9 次判断为库存不够 (库存负数是不正确的 不允许的)
仅在查询语句上 加 for update 加锁效果不大
三、mysql 的事务,锁住操作的行
调整回 product 表 id =1 name = 稻花香大米 store = 15
请求总数30 每次10个并发
- ab -n 30 -c 10 http://xxxxx.top/code/the_limit/ACID.php
结果:
有 15 次库存减少成功 store 库存未出现负数 15 次判断为库存不够 (库存负数是不正确的 不允许的)
加事务 效果不错 ab -n 3000 -c 1000 并发也能扛住
四、 非阻塞的文件排他锁
阻塞形式
非阻塞形式
效果也没有出现负数 但性能上 事务 > 阻塞 > 非阻塞
五、 redis 队列
代码与之前 略有调整 乐观锁版
- <?php
- $redis =new Redis();
- $redis->connect("127.0.0.1", 6379);
- $redis->auth('PASSWORD');
- $redis->watch('sales');//乐观锁 监视作用 set() 初始值0
- $sales = $redis->get('sales');
- //var_dump($sales); exit;
- db();
- global $con;
- // 查询商品信息
- //$product_id = 1;
- //$sql = "select * from products where id={$product_id}";
- //$result = mysqli_query($con, $sql);
- //$row = mysqli_fetch_assoc($result);
- //$store = $row['store'];
- // 库存
- $n = 15;
- if ($sales >= $n) {
- insertLog('库存为0 秒杀失败');
- exit('秒杀结束');
- }
- //redis开启事务
- $redis->multi();
- $redis->incr('sales'); //将 key 中储存的数字值增一 ,如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
- $res = $redis->exec(); //成功1 失败0
- if ($res) {
- //秒杀成功
- $con = new mysqli('localhost','root','PASSWORD','dev');
- if (!$con) {
- echo "数据库连接失败";
- }
- $product_id = 1;// 商品ID
- $buy_num = 1;// 购买数量
- sleep(1);
- $sql = "update products set store=store-{$buy_num} where id={$product_id}";
- if (mysqli_query($con, $sql)) {
- echo "秒杀完成";
- insertLog('恭喜 秒杀成功');
- }
- } else {
- insertLog('抱歉 秒杀失败');
- exit('抢购失败');
- }
- function db()
- {
- global $con;
- $con = new mysqli('localhost','root','WOrd1234.*','dev');
- if (!$con) {
- echo "数据库连接失败";
- }
- }
- /**
- * 记录日志
- */
- function insertLog($content)
- {
- global $con;
- $sql = "INSERT INTO `order_log` (content) values('$content')";
- mysqli_query($con, $sql);
- }
- ab -n 30 -c 10 http://xxxxxx.top/code/the_limit/optimistic\ _redis_lock.php
最终结论 并发挑战 优先 redis 性能好
本文网址:https://www.zztuku.com/index.php/detail-11517.html
站长图库 - PHP高并发实例详解之商品库存超卖并发测试
申明:本文转载于《learnku》,如有侵犯,请 联系我们 删除。
您还没有登录,请 登录 后发表评论!
提示:请勿发布广告垃圾评论,否则封号处理!!