PHPとredisを組み合わせたフラッシュセール商品の詳細説明
productテーブル、orderテーブル
を作成し、
orderテーブルのデータを初期化します。
1.2 製品データを Redis キューに書き込みます。
例えば、商品No.1は100個あります。 100 個の 1 を Goods_1 キューに書き込むだけです。たとえば、ポップ操作の原子性 (同時実行性の保持) を使用して、後で購入する場合は、1 つ購入した後に 1 つポップするだけです。
//代码使用yii 框架,重点在思路,其它框架做少量调整即可。
$redis = self::createRedisObj(); //创建redis 对象,后面提供详细代码
$sql = "select * from sec_goods";
$rows = Yii::app()->db->createCommand($sql)->queryAll();
foreach( $rows as $key => $row ):
$goods_id = $row["id"];
$stock_avail = $row["stock_avail"];
$redis_key = "goods_".$goods_id;
for($i =0 ; $i< $stock_avail; $i++){
$redis->lpush($redis_key , 1);
}
echo $goods_id."llen is ".$redis->lLen($redis_key)."<br/>";
endforeach;
そうです
次に、Apache の ab ガジェットを使用してテストします。-n はリクエストの数を表します。 -c は一度に同時リクエストの数を表します。 0AB -N 1000 -C 100 http://xxx
(上記のコードのトランザクションを削除すると、AB が実行されると爆発的な注文が発生します。時間外問題の詳細をクリックしてください。 トランザクションの分離に基づいて、トランザクションは順次実行される必要があるため、上記のコードは過剰販売や注文の爆発を引き起こすことはありません。 (在庫 10 個のうち 11 個が売り切れました) しかし、このコードにはパフォーマンスの問題があります。つまり、
同時リクエストが何回あるか、データベース
に何回
3 Redisのフラッシュセールコードを終了します。 いよいよメイン料理の提供です。 。 。 。
//用随机值模拟客户,商品,单次购买份数 $uid = rand(1,10); $amount = rand(1,5); $goods_id = rand(1,6); $time = time(); $this->buy($uid , $goods_id , $amount); public function buy($uid , $goods_id , $amount){ //使用行锁. try { $trans = Yii::app()->db->beginTransaction(); $sql = "select stock_avail from sec_goods where id = $goods_id for update"; // $stock_avail = Yii::app()->db->createCommand($sql)->queryScalar(); if( $stock_avail >= $amount ){ //份额足够。 $sn = date("YmdHis")."-".$uid."-".$goods_id.rand(1000,9999); $sql = "insert into sec_order set sn = '$sn',user_id = $uid, goods_id = $goods_id, create_at = $time,num = $amount"; $bool = Yii::app()->db->createCommand($sql)->execute(); if( !$bool ){ throw new Exception("执行失败".$sql); } $sql = "update sec_goods set stock_avail = stock_avail - $amount where id= $goods_id"; $bool = Yii::app()->db->createCommand($sql)->execute(); if( !$bool ){ throw new Exception("执行失败".$sql); } } $trans->commit(); return true; } catch (Exception $e) { //日志记录 $trans->rollback(); return false; } }
通常、redis はキャッシュ用のフレームワークと結合されます。上記の例では、redis オブジェクトを作成するときに別のライブラリを指定することに注意してください。 (redis には通常 9 つのオプションがあります) サーバーがキャッシュをクリアするときにデータがクリアされないようにします。 おめでとうございます。上記のコードで基本バージョンが完成しました。
------------------------------------------------- --------------------------------------------------しかし現在、この現象は運用上のニーズに応じて変化し続けるでしょう。
例を挙げてみましょう。
1 製品は 1 人のユーザーによって 3 秒以内に 1 回のみ購入されることが想定されます。 商品はありません 2 商品 1 人のユーザーが 1 つの商品を最大 5 個まで購入できることを希望します。
この状況に遭遇した場合
問題 1 は次のように処理されます
//code 3.1 //用随机值模拟客户,商品,单次购买份数 $uid = rand(1,10); $amount = rand(1,5); $goods_id = rand(1,6); $time = time(); //用redis 校验,此次用户是否可以买。(库存是否充足) $redis = self::createRedisObj(); $redis_key = "goods_".$goods_id; $len = $redis->lLen($redis_key); //求队列的长度,也就是商品的库存。 if( $len == 0 ){ exit("抢光了!"); } else if( $len < $amount){ exit("库存不足!"); } //验证通过,开始pop 出队列。 pop 一个,相当于买一个。 for( $i =0 ; $i< $amount;$i++){ $redis->rPop( $redis_key ); } $bool = $this->buy($uid , $goods_id , $amount); if( !$bool ) { //如果购买失败,则把取出的redis 队列的数据,再压回去。(回充库存) for( $i =0 ; $i< $amount;$i++){ $redis->lPush( $redis_key , 1); } } //创建redis 对象的。 private static $_redis = null; /** * 创建一个redis 对象. * @return Redis */ public static function createRedisObj(){ //2017-11-29 改为单例创建模式. if( ! self::$_redis){ $redis = new Redis(); $host = “192.168.1.xx”; $port = "6379"; $redis->connect($host,$port); self::$_redis = $redis; } return self::$_redis; }
// 購入後のプロセス。 。 。 。 。
質問2は次のように修正されます。
//用随机值模拟客户,商品,单次购买份数 $uid = rand(1,10); $amount = rand(1,5); $goods_id = rand(1,6); $time = time(); $redis = self::createRedisObj(); ////////////单用户限3秒内仅允许请求一次/////////////////////////////// $lock_key = "uTimeLimit_".$uid; //按用户名编即可。 如果限用户针对指定商品,则lock_key 按uid+ goods_id 进行唯一编码 if( $redis->get($lock_key)){ $left_time = $redis->ttl($lock_key); exit($expire ."秒内只允许 $tag 一次!请".$left_time."之后再尝试"); }else { $redis->setEx($lock_key , $expire , "1" ); } ////////////////////////////////////////////////////////////////// //用redis 校验,此次用户是否可以买。(库存是否充足) $len = $redis->lLen($redis_key); //求队列的长度,也就是商品的库存。 if( $len == 0 ){ exit("抢光了!"); }else if( $len < $amount){ exit("库存不足!"); }
これら 2 つの問題はすでに解決されており、他の同様の問題もできるだけ早く解決される予定です。注意深い読者であれば、このような変更には共通点があり、再利用しやすくするためにコードを適切にカプセル化できることがわかります。
関連する推奨事項:
PHP を Redis と組み合わせて、一定期間内のユーザーまたは IP によるアクセス数を制限する
PHP を Linux cron コマンドと組み合わせて、スケジュールされたタスクの例を実装する
以上がPHPとredisを組み合わせたフラッシュセール商品の詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Redisクラスターモードは、シャードを介してRedisインスタンスを複数のサーバーに展開し、スケーラビリティと可用性を向上させます。構造の手順は次のとおりです。異なるポートで奇妙なRedisインスタンスを作成します。 3つのセンチネルインスタンスを作成し、Redisインスタンスを監視し、フェールオーバーを監視します。 Sentinel構成ファイルを構成し、Redisインスタンス情報とフェールオーバー設定の監視を追加します。 Redisインスタンス構成ファイルを構成し、クラスターモードを有効にし、クラスター情報ファイルパスを指定します。各Redisインスタンスの情報を含むnodes.confファイルを作成します。クラスターを起動し、CREATEコマンドを実行してクラスターを作成し、レプリカの数を指定します。クラスターにログインしてクラスター情報コマンドを実行して、クラスターステータスを確認します。作る

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHPは、シンプルな構文と高い実行効率を備えたWeb開発に適しています。 2。Pythonは、簡潔な構文とリッチライブラリを備えたデータサイエンスと機械学習に適しています。

PHPの将来は、新しいテクノロジーの傾向に適応し、革新的な機能を導入することで達成されます。1)クラウドコンピューティング、コンテナ化、マイクロサービスアーキテクチャに適応し、DockerとKubernetesをサポートします。 2)パフォーマンスとデータ処理の効率を改善するために、JITコンパイラと列挙タイプを導入します。 3)パフォーマンスを継続的に最適化し、ベストプラクティスを促進します。

PHPは死にかけていませんが、常に適応して進化しています。 1)PHPは、1994年以来、新しいテクノロジーの傾向に適応するために複数のバージョンの反復を受けています。 2)現在、電子商取引、コンテンツ管理システム、その他の分野で広く使用されています。 3)PHP8は、パフォーマンスと近代化を改善するために、JITコンパイラおよびその他の機能を導入します。 4)Opcacheを使用してPSR-12標準に従って、パフォーマンスとコードの品質を最適化します。

Redisはハッシュテーブルを使用してデータを保存し、文字列、リスト、ハッシュテーブル、コレクション、注文コレクションなどのデータ構造をサポートします。 Redisは、スナップショット(RDB)を介してデータを維持し、書き込み専用(AOF)メカニズムを追加します。 Redisは、マスタースレーブレプリケーションを使用して、データの可用性を向上させます。 Redisは、シングルスレッドイベントループを使用して接続とコマンドを処理して、データの原子性と一貫性を確保します。 Redisは、キーの有効期限を設定し、怠zyな削除メカニズムを使用して有効期限キーを削除します。

Redisのすべてのキーを表示するには、3つの方法があります。キーコマンドを使用して、指定されたパターンに一致するすべてのキーを返します。スキャンコマンドを使用してキーを繰り返し、キーのセットを返します。情報コマンドを使用して、キーの総数を取得します。

H5開発で習得する必要があるツールとフレームワークには、Vue.JS、React、Webpackが含まれます。 1.Vue.jsは、ユーザーインターフェイスの構築に適しており、コンポーネント開発をサポートします。 2.複雑なアプリケーションに適した仮想DOMを介したページレンダリングを最適化します。 3.Webpackは、モジュールのパッケージングに使用され、リソースの読み込みを最適化します。

Redis-Serverが見つからない問題を解決するための手順:インストールを確認して、Redisが正しくインストールされていることを確認します。環境変数Redis_hostとredis_portを設定します。 Redis Server Redis-Serverを起動します。サーバーがRedis-Cli pingを実行しているかどうかを確認します。
