• 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));

    尚在改进,如果有改进或者其他看法请留言,一同探讨

  • 相关阅读:
    c#读取文件内容存放到int数组 array.txt
    YxShop_V4.2.0开源免费商城2009新春版发布,整合dz最新版,开源!
    c# 读取xml文件 "分析 EntityName 时出错"的解决方案
    正则表达式口诀
    c#操作xml文件
    在WebClient类中保持Session
    实测SCSI RAID速度
    朋友送我的一套书
    给LFF占了个板凳
    ECC内存也能坏
  • 原文地址:https://www.cnblogs.com/hualingyun/p/9438268.html
Copyright © 2020-2023  润新知