php商城秒杀,可以购买多件商品,redis防高并发

<?php

header(‘content-type:text/html;charset=utf-8‘);
echo time();
class SeckillRedis {

static protected $validity_time = 30; // 有效期 5分钟
 protected $goods_id;
 protected $user_queue_key;
 protected $goods_number_key;
 protected $user_id;

public function __construct($goods_id,$area_id,$uid){
  if($goods_id){
   $this->goods_id=$goods_id;
   //当前商品队列的用户情况
   $this->user_queue_key="goods_".$goods_id."_user";
   //当前商品的库存队列
   $this->goods_number_key="goods_".$goods_id;
  }
  $this->user_id=$uid ? $uid : 2;
 }
 
 /* redis链接 */

static public function getRedis(){
  $redis=new Redis();
  $redis->connect(‘127.0.0.1‘,‘6379‘) or die(‘Can not Content Redis‘);
  if($redis){
   return $redis;
  }else{
   die(‘Can not Content Redis!‘);
  }
 }

// 添加或改变库存时初始化队列
 public function kuCun($num){
  $redis=$this->getRedis();
  $redis->delete($this->goods_number_key);
  // $redis->delete($this->user_queue_key);
  for ($i=0; $i < $num; $i++) {

$redis->rPush($this->goods_number_key, 1);

}
 }

// 判断未支付订单是否过期 ,定时更新秒杀商品入口人数

public function poling_set_seckill_redis(){
  $redis=$this->getRedis();
  //exists检查key是否存在,存在返回1,不存在返回0,0也属于不存在的
  if($redis->exists($this->user_queue_key) == true){

// 清除过期的使用数量

$use_list = $redis->lRange($this->user_queue_key, 0, -1);
   // var_dump($use_list);
   foreach ($use_list as $k => $v) {

$data = json_decode($v, true);

if(time() - $data[‘time‘] > self::$validity_time){

// 超过有效期 删除

$this->returnFree($k,$data[‘uid‘],$data[‘num‘]);

}

}

}

}
 
 /* 获取空闲抢购--num:购买件数 */

public function getFree($num){

if(empty($this->user_id)){

return array(‘result‘ => false, ‘message‘ => ‘抢购信息:用户ID不能为空‘);

}

$redis = self::getRedis();

if($redis->llen($this->goods_number_key)>=$num){
   for ($i=0; $i < $num; $i++) {
    $result = $redis->lPop($this->goods_number_key);
   }
   // $result = $redis->lrem($this->goods_number_key,‘1‘,$num);
   // var_dump($redis->lrange($seckill_array[$type][‘free_key‘],0,-1));
   if($result == true){

// 添加使用数量

$index = $redis->rPush($this->user_queue_key, json_encode(array(‘uid‘ => $this->user_id, ‘time‘ => time(),‘num‘ => $num))) - 1;

return array(‘result‘ => true, ‘index‘ => $index);

}else{

return array(‘result‘ => false, ‘message‘ => ‘抢购信息:被抢光啦‘);

}
  }else{
   return array(‘result‘ => false, ‘message‘ => ‘抢购信息:库存不够‘);
  }

}

/* 返回空闲抢购--$index为键值 */

public function returnFree($index,$uid,$num){

$redis = self::getRedis();

$value = $redis->lGet($this->user_queue_key,$index);
  var_dump($value.‘hh‘);
  if(!empty($value)){

$redis->lRem($this->user_queue_key, $value, 1);

// 添加空闲数量
   for ($i=0; $i < $num; $i++) {
    $redis->rPush($this->goods_number_key, 1);
   }

// $sql语句,库存加1

return array(‘result‘ => true);

}else{

return array(‘result‘ => false, ‘message‘ => ‘抢购信息:不存在索引‘);

}

}

}

class Index{

/* 某个需要控制并发的控制器方法 */

public function getOrderInfo(){

$miaosha=new SeckillRedis(‘3‘,‘123‘,‘2‘);
  // $miaosha->kuCun(‘100‘);
  $miaosha->poling_set_seckill_redis();
  $result = $miaosha->getFree(‘1‘);
  return $result;
  if($result[‘result‘] == false){

// 没有机会 返回错误信息

return ‘网络繁忙,请重试‘;

}

// 处理数据库代码

}
}

$hua = new Index;
var_dump($hua->getOrderInfo()).‘<br>‘;
$redis=SeckillRedis::getRedis();

echo $redis->llen(‘goods_3‘);
var_dump($redis->lrange(‘goods_3‘,0,-1));
var_dump($redis->lrange(‘goods_3_user‘,0,-1));

原文地址:https://www.cnblogs.com/hualingyun/p/9438686.html

时间: 2024-10-09 12:40:58

php商城秒杀,可以购买多件商品,redis防高并发的相关文章

PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法

如今在电商行业里,秒杀抢购活动已经是商家常用促销手段.但是库存数量有限,而同时下单人数超过了库存量,就会导致商品超卖甚至库存变负数的问题.又比如:抢购火车票.论坛抢楼.抽奖乃至爆红微博评论等也会引发阻塞式高并发问题.如果不做任何措施可能在高瞬间造成服务器瘫痪,如何解决这个问题呢?这里提出个人认为比较可行的几个思路方法: 方案一:使用消息队列来实现 可以基于例如MemcacheQ等这样的消息队列,具体的实现方案这么表述吧比如有100张票可供用户抢,那么就可以把这100张票放到缓存中,读写时不要加锁

微博热搜、天猫秒杀、12306抢票,都是高并发,难点相同吗?

又是一年春运抢票时,12306 又挂了.同为高并发,微博热搜.天猫秒杀.12306 抢票有什么不同呢? 本文完全基于个人的有限的经验和了解,如果文中有什么问题还请大家一起讨论和指正. 微博热搜 「微博热搜」是一个典型的读多写少场景.读今日的热点新闻,写自己的微博评论. 作为一个后端开发,看到"读多写少",第一反应就应该想到要加缓存. 可是,为什么微博总是宕机,抵挡不住 xxx 明星出轨新闻流量? 对微博来说,难点在于热点无法预测,在面对突发流量时,如何快速扩容. 电商秒杀 电商秒杀的大

Java高并发秒杀API之web层

第1章 设计Restful接口 1.1前端交互流程设计 1.2 学习Restful接口设计 什么是Restful?它就是一种优雅的URI表述方式,用来设计我们资源的访问URL.通过这个URL的设计,我们就可以很自然的感知到这个URL代表的是哪种业务场景或者什么样的数据或资源.基于Restful设计的URL,对于我们接口的使用者.前端.web系统或者搜索引擎甚至是我们的用户,都是非常友好的. 第2章 SpringMVC整合spring 2.1 SpringMvc理论 蓝色部分是需要我们自己开发的

Redis优化高并发下的秒杀性能

本文内容 使用Redis优化高并发场景下的接口性能数据库乐观锁 随着双12的临近,各种促销活动开始变得热门起来,比较主流的有秒杀.抢优惠券.拼团等等.涉及到高并发争抢同一个资源的主要场景有秒杀和抢优惠券. 前提 活动规则 奖品数量有限,比如100个 不限制参与用户数 每个用户只能参与1次秒杀 活动要求 不能多发,也不能少发,100个奖品要全部发出去 1个用户最多抢1个奖品 遵循先到先得原则,先来的用户有奖品 数据库实现 悲观锁性能太差,本文不予讨论,讨论一下使用乐观锁解决高并发问题的优缺点.数据

一文带你了解Redis优化高并发下的秒杀性能

本文内容 使用Redis优化高并发场景下的接口性能数据库乐观锁 随着双12的临近,各种促销活动开始变得热门起来,比较主流的有秒杀.抢优惠券.拼团等等.涉及到高并发争抢同一个资源的主要场景有秒杀和抢优惠券. 前提 活动规则 奖品数量有限,比如100个 不限制参与用户数 每个用户只能参与1次秒杀 活动要求 不能多发,也不能少发,100个奖品要全部发出去 1个用户最多抢1个奖品 遵循先到先得原则,先来的用户有奖品 数据库实现 悲观锁性能太差,本文不予讨论,讨论一下使用乐观锁解决高并发问题的优缺点.数据

商城秒杀活动要点

商城秒杀的特性: 1.定时秒杀.即商品在秒杀时间点之前是不能进行购买下单.业务较简单. 2.秒杀前用户会频繁刷新秒杀页面. 3.秒杀持续时间短.瞬时访问流量高. 4.同一用户/IP禁止秒杀多次. 秒杀系统设计要点: 1.将秒杀系统独立部署,甚至使用独立域名,使其与原有网站完全隔离.主要防止秒杀对现有网站业务造成冲击. 2.页面静态化:将活动页面上的所有可以静态的元素全部静态化,并尽量减少动态元素.通过CDN来抗峰值. 3.禁止重复提交:用户提交之后按钮置灰,禁止重复提交 用户限流:在某一时间段内

PHP高并发商城秒杀

1.什么是秒杀 秒杀活动是一些购物平台推出的集中人气的活动,一般商品数量很少,价格很便宜,限定开始购买的时间,会在以秒为单位的时间内被购买一空.比如原价千元甚至万元的商品以一元的价格出售,但数量只有一件,在某天的某个时间开始出售,这就造成很多人去抢这一件商品.当然想抢到是需要很多因素的,比如你的电脑配置.网速,还有你的运气. 2.秒杀会带来的问题 (1).高并发 比较火热的秒杀在线人数都是10w起的,如此之高的在线人数对于网站架构从前到后都是一种考验. (2).超卖 任何商品都会有数量上限,如何

购买 In-app Billing 商品

购买 In-app Billing 商品 一旦你的应用连接上了 Google Play,你就可以初始化内购商品的购买请求了.Google Play 提供了结算接口,可以让用户进入使用他们的支付方式,所以你的程序不必直接处理支付交易. When an item is purchased, 当一个商品被购买后,Google Play 会认为这个用户已经拥有了此商品,并且直到这个商品被”消耗“后才会让用户再购买一个有相同商品ID的商品.你可以在你的程序里控制如何消耗商品,消耗后再告诉Google Pl

iOS IAP 一次支付,购买一种商品多次

在游戏中,常常需要购买虚拟货币,如:100钻石包 和 200钻石包两种商品,我需要一次购买1000个钻石,就需要购买10次100钻石包或者5次200钻石包.这个时候就需要用到SKMutablePayment这个东西了. //购买一次 SKPayment * payment = [SKPayment paymentWithProduct:_skProducts[0]]; [[SKPaymentQueue defaultQueue] addPayment:payment]; //购买一种商品多次 S