设计思路:redis保存2个list,一个是空闲列表简称A,一个是使用中列表简称B,初始化A的个数是1000,B的个数为0,,我们首先控制进入确认订单页的人数最大为1000,即是用户a点击进入确认订单页,先pop A列表,如果能pop出,表示是1000以内,然后push当前时间信息到B列表,用户a处理完后释放B列表,把使用机会换给A列表,这样就能控制最大的并发数为1000。也是需要守护进程定时去查询B列表中过期的机会归还给A列表。具体代码:

操作redis类:

<?phpclass SeckillRedis {static protected $total_num_50 = 50; // 可允许抢购总数量static protected $total_num_100 = 100;static protected $total_num_500 = 500;static protected $total_num_1000 = 1000;static protected $validity_time = 300; // 有效期 5分钟static protected $seckill_free_num_50_key = 'seckill_free_num_50'; // 空闲允许抢购数量的redis keystatic protected $seckill_use_num_50_key = 'seckill_use_num_50'; // 被使用的redis keystatic protected $seckill_free_num_100_key = 'seckill_free_num_100';static protected $seckill_use_num_100_key = 'seckill_use_num_100';static protected $seckill_free_num_500_key = 'seckill_free_num_500';static protected $seckill_use_num_500_key = 'seckill_use_num_500';static protected $seckill_free_num_1000_key = 'seckill_free_num_1000';static protected $seckill_use_num_1000_key = 'seckill_use_num_1000';static protected $redisConnect;/* 获取redis链接 */static public function getRedis(){if(empty(self::$redisConnect)){self::$redisConnect = MyRedis::connect('redis');}return self::$redisConnect;}/* 获取所有key数组 */static public function getRedisKeys(){return array(50 => array('free_key' => self::$seckill_free_num_50_key, 'use_key' => self::$seckill_use_num_50_key, 'total_num' => self::$total_num_50),100 => array('free_key' => self::$seckill_free_num_100_key, 'use_key' => self::$seckill_use_num_100_key, 'total_num' => self::$total_num_100),500 => array('free_key' => self::$seckill_free_num_500_key, 'use_key' => self::$seckill_use_num_500_key, 'total_num' => self::$total_num_500),1000 => array('free_key' => self::$seckill_free_num_1000_key, 'use_key' => self::$seckill_use_num_1000_key, 'total_num' => self::$total_num_1000));}/* 设置--初始化 */static public function setSeckillRedisKey($free_key, $use_key, $total_num){$redis = self::getRedis();$redis->delete($free_key);$redis->delete($use_key);for ($i=0; $i < $total_num; $i++) {$redis->rPush($free_key, 1);}}/* 定时更新秒杀商品入口人数 */static public function poling_set_seckill_redis(){$seckill_array = self::getRedisKeys();$redis = self::getRedis();foreach ($seckill_array as $key => $value) {if($redis->exists($value['free_key']) == true){// 清除过期的使用数量$use_list = $redis->lRange($value['use_key'], 0, -1);foreach ($use_list as $k => $v) {$data = json_decode($v, true);if(time() - $data['time'] > self::$validity_time){// 超过有效期 删除self::returnFree($key, $k);}}}else{self::setSeckillRedisKey($value['free_key'], $value['use_key'], $value['total_num']);echo 'set';}}}/* 获取空闲抢购--type:50 100 500 1000 */static public function getFree($type, $uid){$seckill_array = self::getRedisKeys();if(empty($type) || !in_array($type, array_keys($seckill_array))){return array('result' => false, 'message' => '抢购信息:类型不正确');}if(empty($uid)){return array('result' => false, 'message' => '抢购信息:用户ID不能为空');}$redis = self::getRedis();$result = $redis->lPop($seckill_array[$type]['free_key']);if($result == true){// 添加使用数量$index = $redis->rPush($seckill_array[$type]['use_key'], json_encode(array('uid' => $uid, 'time' => time()))) - 1;return array('result' => true, 'index' => $index);}else{return array('result' => false, 'message' => '抢购信息:被抢光啦');}}/* 返回空闲抢购--type:50 100 500 1000 */static public function returnFree($type, $index){$seckill_array = self::getRedisKeys();if(empty($type) || !in_array($type, array_keys($seckill_array))){return array('result' => false, 'message' => '抢购信息:类型不正确');}$redis = self::getRedis();$value = $redis->lGet($seckill_array[$type]['use_key'], $index);if(!empty($value)){$redis->lRem($seckill_array[$type]['use_key'], $value, 1);// 添加空闲数量$redis->rPush($seckill_array[$type]['free_key'], 1);return array('result' => true);}else{return array('result' => false, 'message' => '抢购信息:不存在索引');}}/* 打印 */static public function printRedis($type){$seckill_array = self::getRedisKeys();$redis = self::getRedis();$free_list = $redis->lRange($seckill_array[$type]['free_key'], 0, -1);print_r($free_list);$use_list = $redis->lRange($seckill_array[$type]['use_key'], 0, -1);print_r($use_list);}}

使用例子:

<?phpclass Index extends controller{/* 某个需要控制并发的控制器方法 */public function getOrderInfo(){// 获取操作机会 工具类提供4中限制数量类型 这里控制最大并发数为100$type = 100;$result = SeckillRedis::getFree($type, $_SESSION['uid']);if($result['result'] == false){// 没有机会 返回错误信息return '网络繁忙,请重试';}// 处理数据库代码...........// 处理完毕,归还操作机会SeckillRedis::returnFree($type, $result['index']);}}

PHP结合redis实现秒杀活动大并发相关推荐

  1. Day267.预约系统的性能瓶颈、营销活动无缝切换秒杀活动、预约系统数据迁移方案、高流量下预约系统搭建熔断机制、预约系统redis集群主从哨兵架构 -Redis的高并发预约抢购系统

    一.预约系统的性能瓶颈 1.预约系统应对热门爆品时的缺陷 用户进行预约会涉及到两个维度的数据变更一个是用户信息,一个是SKU信息,如图↓所示: 正常来说这么搞一点问题没有,即便涉及到写数据库,但是每个 ...

  2. php redis incr秒杀,Redis瞬时高并发秒杀方案总结

    1.Redis 丰富的数据结构(Data Structures) 字符串(String) Redis字符串能包含任意类型的数据;: 一个字符串类型的值最多能存储512M字节的内容: 利用INCR命令簇 ...

  3. redis分布式锁实现秒杀活动

    最近,参与和负责公司的一次秒杀活动的设计开发,收获颇多,与大家分享.其实大家在生活中或见过或参见过秒杀活动,用户以极低的成本获得高价值的商品,所以也导致活动期间出现拥挤现象,进而导致一些高并发问题,所 ...

  4. SpringBoot、Redis轻松实现Java高并发秒杀系统笔记

    秒杀项目 优极限[完整项目实战]半天带你用SpringBoot.Redis轻松实现Java高并发秒杀系统 文章目录 秒杀项目 技术栈 课程介绍 学习目标 如何设计一个秒杀系统 项目搭建 分布式会话 登 ...

  5. 【硬核】秒杀活动技术方案,Redis申请32个G,被技术总监挑战了...

    作为一名技术从业人员,性能优化是每个人的必修课 就像大学时期给漂亮妹子修电脑的绝招就是"重启电脑一样",性能优化也有自己的必杀技 你一定听过一句话:性能不够,缓存来凑!对,你没听错 ...

  6. .NetCore+Jexus代理+Redis模拟秒杀商品活动

    开篇叙 ,顺手点个推荐也不错: a. 秒杀流程 b. 封装StackExchange.Redis的使用类 c. Ubuntu16.04上使用Jexus搭建代理完成分布式部署 d. NetCore写实时 ...

  7. 阿里双11大促秒杀活动下的缓存技术与高水位限流实现

    秒杀最早来自天猫双11各种商品的促销活动中,现在已经有很多业务场景在使用,比如抢红包,抢票等.其特点有三高:瞬时并发高,数据一致性高,热点更新频度高.这样三高的场景下往往给数据库造成极大的压力,大量更 ...

  8. 阿里、百度、美团都在用的‘’高并发秒杀系统‘’;抢红包、秒杀活动、微博热搜、12306抢票等高并发场景

    "秒杀活动"."抢红包"."微博热搜"."12306抢票"."共享单车拉新"等都是高并发的典型业务场 ...

  9. php redis下单,redis 队列简单实现高并发抢购/秒杀

    redis 队列简单实现高并发抢购/秒杀 2019-03-21 14:34 阅读数 82 前提为每人限购1件 <>开抢前 把秒杀商品库存存进 Redis 队列中 $redis = new ...

  10. java高并发秒杀活动的各种简单实现

    最近遇到比较多数据不一致的问题,大多数都是因为并发请求时,没及时处理的原因,故用一个比较有代表性的业务场景[活动秒杀]来模拟一下这个这种高并发所产生的问题. 众所周知,电商系统的秒杀活动是高并发的很好 ...

最新文章

  1. java中包的_Java中的包
  2. python之commands模块
  3. 排序 (2)快速排序
  4. AndroidManifest.xml中Activity ConfigChanges属性的用法
  5. 17种常用的JS正则表达式 非负浮点数 非负正数
  6. java 程序是由什么组成的 java_从零开始的JAVA -2. java程序的构成及命名规则
  7. 成都鸿蒙脱模剂厂家,现场体验荣耀智慧屏与鸿蒙OS,荣耀Life成都店与您共享锐科技...
  8. 解决ipad,ios录屏保存失败-5823
  9. 【java】两个线程如何交替执行,一个输出偶数一个输出奇数?
  10. HCIE-Security Day29:IPSec:实验(四)总部与分支机构之间建立IPSec PN(采用策略模板方式,总部采用固定IP)
  11. 上位机与西门子PLC通信协议
  12. 常见文件扩展名和它们的说明
  13. win10c盘扩容_三招给你的C盘瘦身
  14. excel合并两列内容_技巧不求人169期 Excel打印最常用的8大技巧 Excel合并多表数据...
  15. 51单片机蜂鸣器播放音乐C语言程序实例,51单片机 使用蜂鸣器播放简单音乐
  16. 【“科大讯飞杯”第十七届同济大学】A 张老师和菜哭武的游戏
  17. 前端Jquery使用pagination.js插件进行分页
  18. Docker学习之数据卷操作:Day4
  19. 程序员面试金典-刷题笔记
  20. 基于SVM的车牌识别

热门文章

  1. python中的counter函数_Python的 counter内置函数,统计文本中的单词数量
  2. HTML:让img标签和input标签水平对齐一样高
  3. alert确认后执行_微任务、宏任务、DOM渲染的执行顺序
  4. Java自然语言处理NLP工具包
  5. python c++ socket 通信一个示例
  6. 论文笔记_S2D.34-2015-CVPR_从单张图像进行深度估计的深度卷积神经场
  7. 分布式存储系统学习笔记(一)—什么是分布式系统(3)—复制
  8. 【3.2】抽象基类(abc模块)
  9. CSS深入理解之border
  10. 请假系统特例规则详细设计