php商城秒杀,redis防高并发
<?php header('content-type:text/html;charset=utf-8'); class SeckillRedis { static protected $validity_time = 300; // 有效期 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(){ //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']); } } } } /* 获取空闲抢购--type:50 100 500 1000 */ public function getFree(){ if(empty($this->user_id)){ return array('result' => false, 'message' => '抢购信息:用户ID不能为空'); } $redis = self::getRedis(); $result = $redis->lPop($this->goods_number_key); // 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()))) - 1; return array('result' => true, 'index' => $index); }else{ return array('result' => false, 'message' => '抢购信息:被抢光啦'); } } /* 返回空闲抢购--$index为键值 */ public function returnFree($index,$uid){ $redis = self::getRedis(); $value = $redis->lGet($this->user_queue_key,$index); if(!empty($value)){ $redis->lRem($this->user_queue_key, $value, 1); // 添加空闲数量 $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'); $result = $miaosha->getFree(); 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));
尚在改进,如果有改进或者其他看法请留言,一同探讨