ホームページ  >  記事  >  データベース  >  Redis を使用してフラッシュ セール サポート デモを作成する方法

Redis を使用してフラッシュ セール サポート デモを作成する方法

WBOY
WBOY転載
2023-05-27 08:22:481456ブラウズ

Redis を使用してフラッシュ セールの在庫を差し引き、各アカウントを 1 つのスナップアップのみに制限します。この簡単なデモでは、文字列、ハッシュ、リストの 3 つの基本タイプを使用します。文字列 残りの在庫を保存するには int 値を入力し、スナップアップが成功した後にそれを 1 減らします。

  • ハッシュを使用して「販売済み」メンバーの ID を保存します (あなたはユーザー ID がフィールド プロパティ内の唯一の ID であることを確認できます)。注: このハッシュのフィールドに対応する UID が必ずしも購入に成功するとは限りません。

  • リストを使用して、実際に購入に成功したメンバー ID のリストを、後続の注文処理のキューとして保存します。

  • 最初にこれを書いたとき、文字列ビットマップを使用して保存しようとしました。メンバーが正常に購入したかどうかを確認しますが、同時実行性が高い場合に問題が発生するため、後で一意のフィールド ハッシュ
2 ファイル:

に変更しました。 init.php: 初期化された在庫、統計データ、成功したメンバーのリストなど。

  • buy.php: ラッシュ購入

  • 初期化

  • ini.php:
$m_redis = new YourRedisClass(); //redis类很多, 可以自己写, 也可以用predis等
$m_redis->set('rush_stock', 20);//int, 可抢购的商品总数
$m_redis->set('rush_success', 0); //int, 成功的数量
$m_redis->set('rush_fail', 0); //int, 失败的数量
$m_redis->expire('rush_queue_h', 0); //hash, 已加入抢购队列的会员的hash记录表(field是唯一的, 可限制每个uid只有一次), 不一定抢购成功
$m_redis->set('rush_got_uid', ''); //string, 抢购成功的会员uid记录, 只是为了能简单的显示抢到的会员.
$m_redis->del('rush_got_uid_l'); //list, 抢购成功的会员uid(方便抢购后的订单批次处理)
echo 'success, '.date('Y-m-d H:i:s');

このファイルを実行して数量を初期化します。

redis-cli で「mgetrush_stockrush_failrush_successrush_got_uid」を実行して初期化データを確認します

Instakill

判定ロジック:


  • 在庫が0かどうか、在庫が >0 の場合、急ぎ購入キューに入ります

  • ##急ぎ購入キューのデータ (ハッシュ)が正常に書き込まれ、在庫を差し引く準備が整いました

  • ##在庫が差し引かれる場合成功 (剰余 >= 0)、急ぎ購入は成功し、注文処理キュー (リスト) に入ります。
    現在、在庫の保管には文字列 int が使用されていますが、リスト項目も使用できます。カウントする数値、ただし、初期化は文字列型ほど単純ではありません。

    1. buy.php

      //随机生成会员id
      $uid = rand(1,200);
      
      $m_redis = new YourRedisClass(); //redis类很多, 可以自己写, 也可以用predis等
      
      $key = 'rush_stock';
      $q = $m_redis->get($key);
      
      //1. 先判断库存数量
      //库存为0, 直接无法进入抢购队列
      if($q < 1){
          $m_redis->incr(&#39;rush_fail&#39;);//记录失败的数量
          die($uid.&#39;:OutOfStock&#39;);
      }
      
      //2. 判断该会员是否购买过 => 是否进入过队列
      $queued = $m_redis->hSet(&#39;rush_queue_h&#39;, $uid, $uid);//这里只能判断是否进入了抢购的队列. 如果库存为0则无法进入. 进入了队列后才能抢购
      if(!$queued){
          $m_redis->incr(&#39;rush_fail&#39;);//记录失败的数量
          die($uid.&#39;:queue failed&#39;);
      }
      
      //让cpu飞一会
      $n = rand(20000,100000);
      for($i=0; $i < $n; $i++){
          $a = rand(1,20000);
          $a = rand(1,30000);
          $a = rand(1,40000);
          $a = rand(1,50000);
          $a = rand(1,60000);
          $a = rand(1,70000);
          $a = rand(1,80000);
          $a = rand(1,90000);
      }
      
      
      //3. 扣减数量
      $q = $m_redis->decr($key, 1);//扣减数量后会返回结果值
      echo $q.&#39; left:&#39;;
      
      
      ////region 如果不判断操作后返回的结果,则可能会造成超发
      //$m_redis->incr(&#39;q_success&#39;);//记录成功的数量  ==>这个是有bug的, 不可取
      //die(&#39;:success&#39;);
      ////endregion
      
      if($q < 0){
          $m_redis->incr(&#39;rush_fail&#39;);//记录失败的数量
          die($uid.&#39;:decrease fail&#39;);
      }else{
          //记录成功的数量
          $m_redis->incr(&#39;rush_success&#39;);
          //记录该会员已购买
          $m_redis->append(&#39;rush_got_uid&#39;, $uid.&#39;,&#39;); //字符串追加
          $m_redis->rPush(&#39;rush_got_uid_l&#39;, $uid); //list
          die($uid.&#39;:success&#39;);
      }

      上記のコードのハッシュはメンバー uid を保存します。急ぎ購入キューに入っただけでは、必ずしも急ぎ購入が成功するとは限りません。急ぎ購入キューにまったく入っていない人は、このハッシュには含まれず、在庫が 0 であるため直接拒否されます。
    AB ストレス テスト: 単純な 500 個の同時リクエストを作成し、合計 2,000 個のリクエストを試します (テスト中、win10 では 600 個の同時リクエスト後に Nginx がハングアップします)
    Apache路径bin>ab -n 2000 -c 500 http://xxx.com/buy.php

    redis-cli で「mgetrush_stockrush_failrush_successrush_got_uid」を実行します。結果を確認するには、rush_stock の値で過剰発行の可能性のある数を確認します。

    「hvalsrush_queue_h」を実行して、急ぎ購入キューに入っているユーザー ID を確認します。この数値 >= 発行済みのユーザーの数を確認します。

    リスト キューの場合 データ操作には、FIFO データ処理シーケンスを実装できる

    BLPOP

    コマンドを使用できます。

    以上がRedis を使用してフラッシュ セール サポート デモを作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。