Maison >développement back-end >tutoriel php >Explication détaillée de la mise en œuvre et de l'application de la file d'attente de messages PHP (avec organigramme)
lpop/rpop pour supprimer les données de la liste et obtenir la valeur supprimée
// Spike.php 秒杀程序if(Redis::llen('lottery') <pre class="brush:php;toolbar:false">// Warehousing.php 入库程序while(true){ $user = Redis::rpop('lottery'); if (!$user || $user == 'nil') { sleep(2); continue; } $user_arr = explode($user, '%'); $insert_user = [ 'uid' => $user_arr[0], 'time' => $user_arr[1] ]; $res = DB::table('lottery_queue')->insert($insert_user); if (!$res) { Redis::lpush('lottery', $user); }}
Si la concurrence dans le code ci-dessus est trop grande, il y aura des situations de survente. À ce stade, vous pouvez utiliser des verrous de fichiers ou des verrous distribués Redis pour le contrôle. Mettez d'abord les produits dans la liste Redis et utilisez rpop, si vous ne pouvez pas l'obtenir, cela signifie qu'il est épuisé
// 先将商品放入redis中 $goods_id = 2; $sql = select id,num from goods where id = $goods_id; $res = DB::select($sql); if (!empty($res)) { // 也可以指定多少件 Redis::del('lottery_goods' . $goods_id); for($i=0;$i<pre class="brush:php;toolbar:false"> // 开始秒杀 $count = Redis::rpop('lottery_goods' . $goods_id); if (!$count) { // 商品已抢完 ... } // 用户抢购队列 $user_list = 'user_goods_id_' . $goods_id; $user_status = Redis::sismember($user_list, $user_id); if ($user_status) { // 已抢过 ... } // 将抢到的放到列表中 Redis::sadd($user_list, $uid); $msg = '用户:' . $uid . '顺序' . $count; Log::info($msg); // 生成订单等 ... // 减库存 $sql = update goods set num = num -1 where id = $goods_id and num > 0; // 防止超卖 DB::update($sql) // 抢购成功
rabbitmq
Architecture et principe
// Send.php require_once __DIR__.'/vendor/autoload.php'; use PhpAmqpLib\Connection\AMQPStreamConnection; use PhpAmqpLib\Message\AMQPMessage; $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest'); // 创建通道 $channel = $connection->channel(); // 声明一个队列 $channel->queue_declare('user_email', false, false, false, false); // 制作消息 $msg = new AMQPMessage('send email'); // 将消息推送到队列 $channel->basic_publish($msg, '', 'user_email'); echo '[x] send email'; $channel->close(); $connection->close();
// Receive.php require_once __DIR__.'/vendor/autoload.php'; use PhpAmqpLib\Connection\AMQPStreamConnection; use PhpAmqpLib\Message\AMQPMessage; $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest'); //创建通道 $channel = $connection->channel(); $channel->queue_declare('user_email', false, false, false, false); // 当收到消息时的回调函数 $callback = function($msg){ //发送邮件 echo 'Received '.$msg->body.'\n'; }; $channel->basic_consume('user_email', '', false, true, false, false, $callback); // 保持监听状态 while($channel->is_open()){ $channel->wait(); }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!