ホームページ  >  記事  >  バックエンド開発  >  PHPとredisでモールフラッシュセール機能のコード共有を実現

PHPとredisでモールフラッシュセール機能のコード共有を実現

小云云
小云云オリジナル
2018-02-09 09:18:344718ブラウズ

この記事はモールのフラッシュセール機能を実現するためのphp+redisを中心に紹介していますので、興味のある方は参考にしていただければ幸いです。

1. redis をインストールし、独自の php バージョンに応じて対応する redis 拡張機能をインストールします (この手順について簡単に説明します)

1.1. ここでは、php_igbinary.dll、php_redis.dll 拡張機能をインストールします。図内:

1.2.php.ini ファイルには 2 つの新しい拡張子があります: extension=php_igbinary.dll;extension=php_redis.dll

ok ここで、redis 環境を構築するための最初のステップが完了しました。 phpinfo

2. Redis は実際にプロジェクト

2.1 で使用されます。最初のステップは、Redis インストールのデフォルトのポートは 6379 です:


rreee

2.2。実際の関数で使用されます:


<?php
/* 数据库配置 */
return array(
  &#39;DATA_CACHE_PREFIX&#39; => &#39;Redis_&#39;,//缓存前缀
  &#39;DATA_CACHE_TYPE&#39;=>&#39;Redis&#39;,//默认动态缓存为Redis
  &#39;DATA_CACHE_TIMEOUT&#39; => false,
  &#39;REDIS_RW_SEPARATE&#39; => true, //Redis读写分离 true 开启
  &#39;REDIS_HOST&#39;=>&#39;127.0.0.1&#39;, //redis服务器ip,多台用逗号隔开;读写分离开启时,第一台负责写,其它[随机]负责读;
  &#39;REDIS_PORT&#39;=>&#39;6379&#39;,//端口号
  &#39;REDIS_TIMEOUT&#39;=>&#39;300&#39;,//超时时间
  &#39;REDIS_PERSISTENT&#39;=>false,//是否长连接 false=短连接
  &#39;REDIS_AUTH&#39;=>&#39;&#39;,//AUTH认证密码 
);
?>

2.3. フラッシュセールの核心 問題は、大量の同時購入の場合、購入が在庫を超えないことです。これが処理の鍵です。最初のステップとして、フラッシュ セール カテゴリで基本的なデータ生成を行うことです:


/**
    * redis连接
    * @access private
    * @return resource
    * @author bieanju
    */
  private function connectRedis(){
    $redis=new \Redis();
    $redis->connect(C("REDIS_HOST"),C("REDIS_PORT"));    
    return $redis;
  }

2.4。2 番目のステップは、重要な点は、ユーザーが製品詳細ページに入る前に、まず現在の製品在庫をキューに入れ、次のように redis に保存します。


//现在初始化里面定义后边要使用的redis参数
public function _initialize(){
    parent::_initialize();
    $goods_id = I("goods_id",&#39;0&#39;,&#39;intval&#39;);   
    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[&#39;uid&#39;];   
  }

次に行うことは、ユーザーが購入ボタンをクリックしたときに条件を満たすデータを非同期に処理することです (現在のユーザーが購入キューに入っていない場合)。現在の製品ユーザーのキューにある場合は、キューに入り、在庫キューをポップし、その場合は廃棄します):


/**
  * 访问产品前先将当前产品库存队列
  * @access public
  * @author bieanju
  */
  public function _before_detail(){
    $where[&#39;goods_id&#39;] = $this->goods_id;
    $where[&#39;start_time&#39;] = array("lt",time());
    $where[&#39;end_time&#39;] = array("gt",time());
    $goods = M("goods")->where($where)->field(&#39;goods_num,start_time,end_time&#39;)->find();
    !$goods && $this->error("当前秒杀已结束!");
    if($goods[&#39;goods_num&#39;] > $goods[&#39;order_num&#39;]){
      $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[&#39;goods_num&#39;]; $i ++) {
          $redis->lpush("{$this->goods_number_key}", 1);
        }
      }
      $resetRedis = $redis->llen("{$this->goods_number_key}");
      if(!$resetRedis){
        $this->error("系统繁忙,请稍后抢购!");
      }
    }else{
      $this->error("当前产品已经秒杀完!");
    }
     
  }

指定されたキュー値を削除するデバッグ関数をアタッチします:


/**
   * 抢购商品前处理当前会员是否进入队列
   * @access public
   * @author bieanju
   */
  public function goods_number_queue(){
    !$this->user_id && $this->ajaxReturn(array("status" => "-1","msg" => "请先登录"));
    $model = M("flash_sale");
    $where[&#39;goods_id&#39;] = $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[&#39;user_id&#39;] = $this->user_id;
        $condition[&#39;goods_id&#39;] = $this->goods_id;
        $condition[&#39;prom_type&#39;] = 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" => "系统繁忙,请重试!"));
    }
  }

ここまで来ると、フラッシュ セールの核となる部分はほぼ完成しました。ショッピング カートの処理や注文の処理など、詳細はまだ自分たちで改善する必要があります。それでは、プログラムを実行して Apache 独自のものを使用してみましょう。 ab 簡単なシミュレートされた同時実行テストは次のように実行できます。

実行すると、redis がまったく応答しません。この時点で、redisbin_x32 を選択するという重要な手順が 1 つありません。システムに応じて、redis サービス管理ツール、redis-server.exe をクリックすると、すべてが完了します。

関連する推奨事項: Web ページで自動フラッシュ セールを実現するための


JS スクリプト

フラッシュセールを実現するYiiフレームワークredis+phpの効果分析例

在庫の売れ過ぎを防ぐモールフラッシュセール

以上がPHPとredisでモールフラッシュセール機能のコード共有を実現の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。