php redis下单,redis 队列简单实现高并发抢购/秒杀
redis 队列简单实现高并发抢购/秒杀
2019-03-21 14:34
阅读数 82
前提为每人限购1件
<>开抢前
把秒杀商品库存存进 Redis 队列中
$redis = new redis(); $redis->connect('127.0.0.1', 6379); //库存 $num = 10;
//往队列 goods_store 插入商品, 队列的长度为库存 for($i=0;$ilpush(
'goods_store', 1);
<>开抢中
方法1
前端: 用户点击购买按钮进行form表单提交
后端: 执行下面代码
//用户等待队列 $wait_key = "user_wait"; //库存队列 $store_key = "goods_store"; //根据Redis
hash特性, 设置成功返回1, 旧值被覆盖则返回0, 用来控制同一用户多买现象 $result = $redis->hset($wait_key,
$user_id, $user_id); if($result){ $count = $redis->lpop($store_key); if(!$count)
return '已经抢光了'; //下单流程, 数据库入库等操作 //下单失败或报错则执行 $redis->hdel($wait_key,
$user_id); 和加库存 $redis->lpush('goods_store', 1); 并跳转回上一页提示下单失败 ......
//下单成功则跳转到相应页面 return '抢购成功'; }
问题: 高并发下可能造成服务器压力瞬间过大, 导致数据入库失败, 可将下单入库等流程用crontab定时器异步执行
方法2
前端: 用户点击购买按钮, 按钮变灰防止用户重复点击, 并且弹出小窗口提示排队中
ajax异步调用抢购接口
* 成功: js轮询请求是否下单成功接口
* 成功: 跳转相应页面进行支付流程
* 失败: 提示用户重新进行购买流程
* 失败: 提示用户重新进行购买流程
抢购接口代码
//用户等待队列 $wait_key = "user_wait"; //抢购成功的用户队列 $user_key = "user"; //库存队列
$store_key = "goods_store"; //根据Redis hash特性, 设置成功返回1, 旧值被覆盖则返回0, 用来控制同一用户多买现象
$result = $redis->hset($wait_key, $user_id, $user_id); if($result){ $count =
$redis->lpop($store_key); if(!$count) return '已经抢光了'; $redis->lpush($user_key,
$user_id); return '抢购成功'; }
crontab定时器异步执行下单入库代码
//用户等待队列 $wait_key = "user_wait"; //抢购成功的用户队列 $user_key = "user"; $count =
$redis->rpop($user_key); if(!$count) return; //下单流程, 数据库入库等操作 //下单失败或报错则执行
$redis->hdel($wait_key, $user_id); 和加库存 $redis->lpush('goods_store', 1); ......
是否下单成功接口代码
//数据库查询order订单表返回是否存在未支付订单数据
待解决:
假设用户A流程进行到以下逻辑时
流程1.下单流程, 数据库入库等操作
流程2.下单失败或报错则执行 $redis->hdel($wait_key, $user_id); 和加库存
$redis->lpush('goods_store', 1);
假设1由于未知错误导致程序崩溃, 没有执行2就退出了, 用户A不能重新抢购
假设1由于未知错误导致入库失败, 2在执行 $redis->hdel 失败了, 用户A不能重新抢购
优化:
前端静态资源上CDN
设置nginx的最大连接数
假设秒杀商品库存有10个, 当用户等待队列 user_wait 长度大于 30~100 后的请求全部过滤
添加一个延时队列, 把下单规定时间内没有付款的订单取消掉, 并加库存
附送 Redis 锁简易代码
// 加锁 $random:随机数 $expire_time:有效时间 $lock_status = $redis->set($lock_key,
$random, array('nx', 'ex' => $expire_time)); if($lock_status){ // do something .
..... if($redis->get($lock_key) == $random){ // 解锁 $redis->del($lock_key); } }
php redis下单,redis 队列简单实现高并发抢购/秒杀相关推荐
- SpringBoot +Redis +RabbitMQ 实现高并发限时秒杀
SpringBoot +Redis +RabbitMQ 实现高并发限时秒杀 提示:以下是本篇文章正文内容,下面案例可供参考 一.软件安装 1.安装RabbitMQ docker安装:docker安装R ...
- redis解决“高并发定时秒杀”库存误差问题
前言:高并发的秒杀活动中,通过查询数据库判断是否还有库存,然后对库存字段进行增减,极易出现库存超出或者库存为负的情况,一般来说有3中解决办法(数据库表加锁,memche缓存,redis队列): 我们这 ...
- 一个简单的高并发的回应服务器(5万并发)
一个简单的高并发的回应服务器,主要是使用boost的库! 自己测试过可以达到5万个并发! 程序的下载地址:http://download.csdn.net/detail/guanyijun123/83 ...
- 如何解决高并发,秒杀问题
相信不少人会被这个问题困扰,分享大家一篇这样的文章,希望能够帮到你! 一.秒杀业务为什么难做? 1)im系统,例如qq或者微博,每个人都读自己的数据(好友列表.群列表.个人信息): 2)微博系统,每个 ...
- 【高并发】秒杀系统架构解密,不是所有的秒杀都是秒杀(升级版)!!
写在前面 很多小伙伴反馈说,高并发专题学了那么久,但是,在真正做项目时,仍然不知道如何下手处理高并发业务场景!甚至很多小伙伴仍然停留在只是简单的提供接口(CRUD)阶段,不知道学习的并发知识如何运用到 ...
- PHP高并发商品秒杀问题的解决方案
前言 秒杀会产生一个瞬间的高并发,使用数据库会增加数据库的访问压力,也会降低访问速度,所以我们应该使用缓存,来降低数据库的访问压力: 可以看出这里的操作和原来的下单是不一样的:产生的秒杀预订单不会马上 ...
- 电商网站50W-100W高并发,秒杀功能是怎么实现的?
电商网站50W-100W高并发,秒杀功能是怎么实现的? 在淘宝.天猫.京东等国内大型电商平台"造节"的带领下,国内各电商平台纷纷跟进,双十一.双十二.618等电商专属节日也吸引了大 ...
- 互联网大厂高并发抢购系统架构设计
背景 大家好,这篇文章给大家介绍一个非常经典的去大厂面试经常被问的一个问题,就是瞬时 高并发抢购问题,通常来说,大厂开发的系统经常会遇到一些类似电商秒杀抢购.景点门票高并发抢购.特殊商品(比如口罩)高 ...
- 高并发抢购系统,架构解密......
背景 大家好,这篇文章给大家介绍一个非常经典的去大厂面试经常被问的一个问题,就是瞬时高并发抢购问题. 通常来说,大厂开发的系统经常会遇到一些类似电商秒杀抢购.景点门票高并发抢购.特殊商品(比如口罩)高 ...
最新文章
- Flask的HelloWorld程序
- 报名 | 2019前沿信息科技创新论坛
- linux 内核编译错误 .size expression for copy_user_generic_c does not evaluate to a constant
- linux tomcat apr安装,Linux下Tomcat安装并开启APR模式-Go语言中文社区
- JS中令人发指的valueOf方法介绍
- 【原创】C++关于创建和使用静态链接库
- opencv 基本绘图函数
- 利用MapabcAPI实现基于浏览器的地理定位
- python opencv之cvtColor
- 怎样删除usb计算机连接网络打印机驱动,打印机USB连接安装设置及常见问题处理...
- python--实现汇率转换
- QT颜色对照表,RGB颜色对照表
- 分享 | 将Pytorch模型部署到Movidius神经计算棒
- 第一篇:什么是IT行业
- cdr 2021 卸载
- 信息系统项目管理师必背核心考点(四十三)预期货币价值(EMV)
- 利用PPt画卷积神经网络
- PTA:7-6 奇偶数处理
- Java程序告诉你A股沪深300哪些股票值得投资
- 羊是如何侵略狼的(看后很有感触)