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("当前产品已经秒杀完!");
        }
         
    }

  接下来要做的就是用ajax来异步的处理用户点击购买按钮进行符合条件的数据进入购买的排队队列(如果当前用户没在当前产品用户的队列就进入排队并且pop一个库存队列,如果在就抛出,):

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
     * 抢购商品前处理当前会员是否进入队列
     * @access public
     * @author bieanju
     */
    public function goods_number_queue(){
        !$this->user_id && $this->ajaxReturn(array("status" => "-1","msg" => "请先登录"));
        $model = M("flash_sale");
        $where['goods_id'] = $this->goods_id;
        $goods_info $model->where($where)->find();
        !$goods_info && $this->error("对不起当前商品不存在或已下架!"); 
        /* redis 队列 */  
        $redis $this->connectRedis();
        /* 进入队列  */
        $goods_number_key $redis->llen("{$this->goods_number_key}");
        if (!$redis->hGet("{$this->user_queue_key}"$this->user_id)) {
            $goods_number_key $redis->lpop("{$this->goods_number_key}");
        }
         
        if($goods_number_key){
            // 判断用户是否已在队列
            if (!$redis->hGet("{$this->user_queue_key}"$this->user_id)) {
                // 插入抢购用户信息
                $userinfo array(
                    "user_id" => $this->user_id,
                    "create_time" => time()
                );               
                $redis->hSet("{$this->user_queue_key}"$this->user_id, serialize($userinfo));
                $this->ajaxReturn(array("status" => "1"));
            }else{
                $modelCart = M("cart");
                $condition['user_id'] = $this->user_id;
                $condition['goods_id'] = $this->goods_id;
                $condition['prom_type'] = 1;
        $cartlist $modelCart->where($condition)->count();
                if($cartlist > 0){
                    $this->ajaxReturn(array("status" => "2"));
                }else{
                  
                   $this->ajaxReturn(array("status" => "1"));
                  
                }
                 
            }
             
        }else{
            $this->ajaxReturn(array("status" => "-1","msg" => "系统繁忙,请重试!"));
        }
    }

  附加一个调试的函数,删除指定队列值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public function clearRedis(){
         set_time_limit(0);
         $redis $this->connectRedis();
         //$Rd = $redis->del("{$this->user_queue_key}");
         $Rd $redis->hDel("goods49",'用户id'');
         $a $redis->hGet("goods_49_user"'用户id');
         if(!$a){
             dump($a);
         }
         
         if($Rd == 0){
              exit("Redis队列已释放!");           
         }
     }

  走到此处的时候秒杀的核心基本就完了,细节还需要自己在去完善,像购物车这边的处理还有订单的处理,好吧开始跑程序利用apache自身的ab可以进行简单的模拟并发测试如下:

跑起来,我擦跑步起来redis没有任何反应,此时还少一步重要的步骤就是开启redis服务,请根据自己的系统下一个redisbin_x32或者redisbin_x64的redis服务管理工具,点击redis-server.exe,ok至此全部完成如下图:

一个人静静坐在电脑面前写代码的感觉,那是什么感觉?那是武林高手闭关修炼的感觉。

thinkphp+redis实现秒杀功能(转)的更多相关文章

  1. thinkphp+redis实现秒杀功能

    好久没来整理文章了,闲了没事写篇文章记录下php+redis实现商城秒杀功能. 1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbi ...

  2. thinkphp+redis实现秒杀,缓存等功能

    秒杀是商城常见功能  php+redis是最常见的秒杀功能 1,安装redis,根据自己的php版本安装对应的redis扩展 首先查看phpinfo();php环境信息 2,下载redis https ...

  3. php结合redis实现秒杀功能

    <?php 第一种,简单实现 $conn=mysql_connect("localhost","big","123456"); if( ...

  4. 电商项目中使用Redis实现秒杀功能

    参与过抢购活动就知道,很明显的一点是商即便商品实际没有了也是可以下单成功的,但是在支付的时候会提示你商品没有了. 实现原理:list双向链表 使用redis队列,因为pop操作是原子的,即使有很多用户 ...

  5. php+redis实现电商秒杀功能

    这一次总结和分享用Redis实现分布式锁来完成电商的秒杀功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意思,若有误请谅解 ...

  6. Redis事务和实现秒杀功能的实现

    今天带着学生学习了Redis的事务功能,Redis的事务与传统的关系型数据库(如MySQL)有所不同,Redis的事务不能回滚. Redis中使用multi.exec.discard.watch.un ...

  7. Redis分布式锁实现简单秒杀功能

    这版秒杀只是解决瞬间访问过高服务器压力过大,请求速度变慢,大大消耗服务器性能的问题. 主要就是在高并发秒杀的场景下,很多人访问时并没有拿到锁,所以直接跳过了.这样就处理了多线程并发问题的同时也保证了服 ...

  8. spring boot:redis+lua实现生产环境中可用的秒杀功能(spring boot 2.2.0)

    一,秒杀需要具备的功能: 秒杀通常是电商中用到的吸引流量的促销活动方式 搭建秒杀系统,需要具备以下几点: 1,限制每个用户购买的商品数量,(秒杀价格为吸引流量一般会订的很低,不能让一个用户全部抢购到手 ...

  9. 秒杀功能压测 jmeter--------重要!!!

    线程组里面有三个接口请求,依次为:显示商品列表.登录秒杀平台账户.进行秒杀 对线程组用5000个线程循环10次 设置一下默认配置,之后就不用反复填写了 设置配置文件这个具体功能就是读text文件并且设 ...

随机推荐

  1. python中eval()和json.dumps的使用

    在python中通过requests.get(url)获取json数据,此时可能需要eval进行解析. # -*- coding: utf-8 -*- import requests r = requ ...

  2. <Closing connections idle longer than 60000 MILLISECONDS> <Closing expired connections>

    日志信息如下: 2017-07-05 18:28:34 -18705 [idle_connection_reaper] DEBUG   - Closing expired connections 20 ...

  3. Oracle Shared Pool机制之——Latches, Locks, Pins and Mutexes

    本文中,我们将讨论共享池(Shared Pool)中的各种内存保护结构,即Latches,Locks,Pins和Mutexes. 1.  Lathes 当在库缓冲(Libraray Cache)中创建 ...

  4. 从使用角度看 ReentrantLock 和 Condition

    java 语言中谈到锁,少不了比较一番 synchronized 和 ReentrantLock 的原理,本文不作分析,只是简单介绍一下 ReentrantLock 的用法,从使用中推测其内部的一些原 ...

  5. SSL证书读取

    证书内容: MIIDhDCCAmygAwIBAgIFAV0Imw0wDQYJKoZIhvcNAQELBQAwXDEnMCUGA1UEAwweczUwLTYyLTEzNS0xNS5zZWN1cmVzZX ...

  6. 1-2Controller之Session

    laravel5.5版本. 视频教程是慕课网中的:轻松学会Laravel-表单篇 1-2 /*session简介: 1.由于HTTP协议是无状态(Stateless)的,所以session提供一种保存 ...

  7. sql取大的一个值

    select b.*,             a.recid,             a.keyno  from product b,             (select pcode,     ...

  8. day14-python异常处理

    1.     异常 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行. 一般情况下,在Python无法正常处理程序时就会发生一个异常.异常是Python对象,表示一个错误.当Pyt ...

  9. @ResponseBody中文乱码解决方案

    java web项目,使用了springmvc4.0,用@ResponseBody返回中文字符串,乱码$$ 本以为很简单的问题,不过也找了一个小时. 网上有说这样配置的: <mvc:annota ...

  10. Python Django 之 简单入门

    一.下载Django并安装 1.下载Django 2.安装 二.新建Django project 1.使用django-admin新建mysite 项目 django-admin startproje ...