一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - php+redis實現商城秒殺功能

php+redis實現商城秒殺功能

2019-10-22 11:06一米陽光qqq PHP教程

這篇文章主要為大家詳細介紹了php+redis實現商城秒殺功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下

好久沒來整理文章了,閑了沒事寫篇文章記錄下php+redis實現商城秒殺功能。

1、安裝redis,根據自己的php版本安裝對應的redis擴展(此步驟簡單的描述一下)

1.1.安裝php_igbinary.dll,php_redis.dll擴展此處需要注意你的php版本如圖:

php+redis實現商城秒殺功能

1.2.php.ini文件新增extension=php_igbinary.dll;extension=php_redis.dll兩處擴展

ok此處已經完成第一步redis環境搭建完成看看phpinfo

php+redis實現商城秒殺功能

2、項目中實際使用redis

2.1.第一步配置redis參數如下,redis安裝的默認端口為6379: 

<?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:

/**
    * 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. 秒殺的核心問題是在大并發的情況下不會超出庫存的購買,這個就是處理的關鍵所以思路是第一步在秒殺類的先做一些基礎的數據生成:

//現在初始化里面定義后邊要使用的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如下:

/**
  * 訪問產品前先將當前產品庫存隊列
  * @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一個庫存隊列,如果在就拋出,):

/**
   * 搶購商品前處理當前會員是否進入隊列
   * @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" => "系統繁忙,請重試!"));
    }
  }

附加一個調試的函數,刪除指定隊列值:

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可以進行簡單的模擬并發測試如下:

php+redis實現商城秒殺功能

跑起來,我擦跑步起來redis沒有任何反應,此時還少一步重要的步驟就是開啟redis服務,請根據自己的系統下一個redisbin_x32或者redisbin_x64的redis服務管理工具,點擊redis-server.exe,ok至此全部完成如下圖:

php+redis實現商城秒殺功能

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 双夫1v2| 精品午夜视频 | 性欧美xxxxx护士另类 | 暖暖在线日本 | 图片亚洲va欧美va国产综合 | 成人猫咪maomiav永久网址 | 国产精品一区二区三区免费 | 天天综合色网 | 男同gay作爰视频网站 | 91精品国产9l久久久久 | 任你操视频在线观看 | freee×xx性欧美| 久久婷婷丁香五月色综合啪免费 | www视频在线免费观看 | anal22日本人视频 | 免费观看国产大片资源视频 | 秀婷程仪公欲息肉婷在线观看 | 精品一区二区三区高清免费不卡 | 我在厨房摸岳的乳HD在线观看 | 亚洲AV久久无码精品蜜桃 | 亚州综合网 | 我和黑色丝袜班主任 | 国产一级精品高清一级毛片 | 窝窝午夜精品一区二区 | 亚洲第一天堂无码专区 | 爽好舒服快想要免费看 | 国产精品亚洲va在线观看 | 欧美久久影院 | 关晓彤被调教出奶水的视频 | 国产日韩欧美在线播放 | 天天爱天天做天天爽天天躁 | 午夜在线a亚洲v天堂网2019 | 亚洲乱亚洲乱妇41p国产成人 | 操比图片| 日本一卡二卡3卡四卡无卡网址 | 日韩一区二区三区四区区区 | 亚洲精品综合 | 国产日韩精品欧美一区 | 久久人妻少妇嫩草AV無碼 | 无遮挡激情 | 出a级黑粗大硬长爽猛视频 吃胸膜奶视频456 |