アプリケーション シナリオ:
たとえば、フラッシュ セール。大量の注文が瞬時にデータベースに書き込まれ、データベースが時間内に応答できなくなります。現時点では、Redis をメッセージ キューとして使用し、最初に書き込む必要があるすべてのデータを Redis メッセージ キューに書き込んでから、サーバー上で php-cli プロセスを開始してキュー内のデータをループで読み取ることができます。そしてそれをデータベースに非同期で書き込みます。 Redis をメッセージ キューとして使用すると、メッセージ受信の確認メカニズムがないため、メッセージが失われる可能性があります。大規模なプログラムでは、RabitMQ などを専門的なメッセージ キューとして使用する必要があります。
1. パブリッシュ/サブスクライブ メソッドをメッセージ キューとして使用する
特徴: 1 つのメッセージ パブリッシャー (プロデューサー) が複数のメッセージ サブスクライバー (コンシューマー) に対応できます。メッセージがメッセージ キューにパブリッシュされると、すべてのメッセージ サブスクライバーがメッセージを受信できます。分散メッセージの配信に適しています。クライアントは、ブロッキング方式でパブリッシュ側からのメッセージを待ちます。複数のコンシューマーがメッセージの消費を高速化することはできません。
メッセージ生成:
$params =json_encode(['x_uid' => $x_uid, 'phone' => $phone]); $redis->publish('test',$params); //test表示发布的频道名字
メッセージ消費 (php-cli モード操作):
$redis = new Redis(); $redis->pconnect('127.0.0.1'); //必须用pconnect长连接 //设置redis连接永远不超时。默认60s超时断开连接 $redis->setOption(Redis::OPT_READ_TIMEOUT, -1); $redis->subscribe(array('test'), 'callback'); //test表示频道名字,callback 回调函数名 functioncallback($redis, $chan, $msg){ //对收到的消息进行处理函数 $params = json_decode($msg,true); .... }
pconnect と connect の違い:
connect: connect afterスクリプトが終了してリリースされました。
pconnect: スクリプトの終了後も接続は解放されず、接続は php-fpm プロセスに残ります。
したがって、connect の代わりに pconnect を使用すると、頻繁に確立される Redis 接続の消費量を削減できます。
2. Redis メッセージ キューとしてリストを使用する
特徴: メッセージ プロデューサーはメッセージ コンシューマーに対応します。複数のコンシューマを使用すると、メッセージの消費を高速化できます。
メッセージ生成:
$redis =newRedis(); $redis->connect('127.0.0.1'); //将需要写入数据库的数据全部push到队列(复杂数据可以先json编码成字符串) $list = json_encode(['x_uid' => $x_uid, 'phone' => $phone, 'goods_id' => $goodsId, 'add_time' => time(), 'num_field' => $num_field]); $redis->lpush('winer',$list);
注: brpop 消費データがデータベースに正常に書き込まれない場合、データ損失が発生します。本番データが強く必要な場合は、Redis またはファイルにセカンダリ バックアップを実行する必要があります。
メッセージ消費 (php-cli モード操作):
注: MySQL が接続を積極的に閉じない場合、接続は最大 8 時間後に自動的に切断されます。
<?php //链接数据库 $conn = mysqli_connect("localhost","root","root"); if(!$conn){ die("连接数据库失败:". mysqli_error()); } mysqli_select_db($conn,"api"); //字符转换,读库 mysqli_query($conn,"set character set 'utf8'"); //写库 mysqli_query($conn,"set names 'utf8'"); //连接本地的 Redis 服务 $redis =newRedis(); $redis->connect('127.0.0.1',6379); //设置redis连接永远不超时。默认60s超时断开连接 $redis->setOption(Redis::OPT_READ_TIMEOUT,-1); echo 'Listening...'; $i =1; while(true){ $data = $redis->brpop('winer',0); // 0表示没有接收到参数的情况下,永远不超时断开 $info = json_decode($data[1],true); $x_uid = $info['x_uid']; $phone = $info['phone']; $goods_id = $info['goods_id']; $add_time = $info['add_time']; $num_field = $info['num_field']; //将数组写入数据库、订单 $sql = "insert into hd_hengda11_order (`x_uid`,`phone`,`goods_id`,`add_time`) values ($x_uid,$phone,$goods_id,$add_time)" $re = mysqli_query($conn,$sql); echo $i.'_ok||'; $i++; } ?>
その他:
製品の売れすぎを防ぐためのフラッシュ セール シナリオ:
1. データベース内の製品数量を符号なしに設定します。つまり、負の数値は許可されません。商品数量が負の数に更新された場合、false が返されます。
2. 商品の数量は Redis リストのキューに格納され、ラッシュが発生するたびにキューから要素がポップされます。
//存放商品数量的队列 for($j =1; $j <=10; $j++){ /设置商品数量为10 $re =Redis::lpush(gooods_count,1); }
製品数量ロジックの判断
$count=Redis::lpop('gooods_count'); //$count = Redis::llen('gooods_count'); //llen判断队列长度 if(!$count){ return'已经抢光了哦'; }
Redis 関連の知識の詳細については、Redis 使用法チュートリアル 列を参照してください。
以上がRedis をメッセージキューとして使用できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。