当前位置:首页 > Web开发 > 正文

thinkphp+redis实现秒杀功能

11-13 Web开发

1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下)

  1.1,安装 php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图:

  

技术图片

  1.2,php.ini文件新增 extension=php_igbinary.dll;extension=php_redis.dll两处扩展

ok此处已经完成第一步redis环境搭建完成看看phpinfo

技术图片

2,项目中实际使用redis

  2.1,第一步配置redis参数如下,redis安装的默认端口为6379: 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

 

<?php

/* 数据库配置 */

return array(

    ‘DATA_CACHE_PREFIX‘ => ‘Redis_‘,//缓存前缀

    ‘DATA_CACHE_TYPE‘=>‘Redis‘,//默认动态缓存为Redis

    ‘DATA_CACHE_TIMEOUT‘ => false,

    ‘REDIS_RW_SEPARATE‘ => true, //Redis读写分离 true 开启

    ‘REDIS_HOST‘=>‘127.0.0.1‘, //redis服务器ip,多台用逗号隔开;读写分离开启时,第一台负责写,其它[随机]负责读;

    ‘REDIS_PORT‘=>‘6379‘,//端口号

    ‘REDIS_TIMEOUT‘=>‘300‘,//超时时间

    ‘REDIS_PERSISTENT‘=>false,//是否长连接 false=短连接

    ‘REDIS_AUTH‘=>‘‘,//AUTH认证密码 

);

?>

 

  2.2,实际函数中使用redis:

1

2

3

4

5

6

7

8

9

10

11

 

/**

        * redis连接

        * @access private

        * @return resource

        * @author bieanju

        */

    private function connectRedis(){

        $redis=new \Redis();

        $redis->connect(C("REDIS_HOST"),C("REDIS_PORT"));       

        return $redis;

    }

 

  2.3,秒杀的核心问题是在大并发的情况下不会超出库存的购买,这个就是处理的关键所以思路是第一步在秒杀类的先做一些基础的数据生成:

1

2

3

4

5

6

7

8

9

10

11

 

//现在初始化里面定义后边要使用的redis参数

public function _initialize(){

        parent::_initialize();

        $goods_id = I("goods_id",‘0‘,‘intval‘);      

        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 = $this->user_id ? $this->user_id : $_SESSION[‘uid‘];      

    }

 

  2.4,第二步就是关键所在,用户在进入商品详情页前先将当前商品的库存进行队列存入redis如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

 

/**

    * 访问产品前先将当前产品库存队列

    * @access public

    * @author bieanju

    */

    public function _before_detail(){

        $where[‘goods_id‘] = $this->goods_id;

        $where[‘start_time‘] = array("lt",time());

        $where[‘end_time‘] =  array("gt",time());

        $goods = M("goods")->where($where)->field(‘goods_num,start_time,end_time‘)->find();

        !$goods && $this->error("当前秒杀已结束!");

        if($goods[‘goods_num‘] > $goods[‘order_num‘]){

            $redis = $this->connectRedis();

            $getUserRedis = $redis->hGetAll("{$this->user_queue_key}");

            $gnRedis = $redis->llen("{$this->goods_number_key}");

            /* 如果没有会员进来队列库存 */

            if(!count($getUserRedis) && !$gnRedis){            

                for ($i = 0; $i < $goods[‘goods_num‘]; $i ++) {

                    $redis->lpush("{$this->goods_number_key}", 1);

                }

            }

            $resetRedis = $redis->llen("{$this->goods_number_key}");

            if(!$resetRedis){

                $this->error("系统繁忙,请稍后抢购!");

            }

        }else{

            $this->error("当前产品已经秒杀完!");

        }

         

    }

 

温馨提示: 本文由杰米博客推荐,转载请保留链接: https://www.jmwww.net/file/web/10291.html