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)

Explication détaillée de la mise en œuvre et de l'application de la file d'attente de messages PHP (avec organigramme)

藏色散人
Libérer: 2023-04-11 08:22:02
avant
5339 Les gens l'ont consulté

Le concept, le principe et la mise en œuvre de la file d'attente des messages

Concept

  • Un middleware de la structure de la file d'attente
  • Pas besoin de consommer les messages immédiatement
  • Consommation dans l'ordre par les consommateurs ou les abonnés

Le L'organigramme de base est le suivant : implémentation

  • mysql : Fiable, lente
    Explication détaillée de la mise en œuvre et de lapplication de la file dattente de messages PHP (avec organigramme)redis : traitement rapide et lent des paquets de messages volumineux
Système de messagerie : fiable, hautement professionnel

    Mécanisme de déclenchement des messages
  • Méthode de boucle infinie, l'échec ne peut pas être effectué à temps Restauration
  • Tâches planifiées : pression uniformément répartie , mais avec une limite supérieure sur la capacité de traitement
  • Approche démon

Découplage (système de commande et de livraison)

  • Conception de l'architecture 1 Adopter des tâches planifiées

Lors de l'utilisation du système de traitement de distribution pour le traitement, mettre à jour le statut de la commande qui doit être traitée dans la base de données actuelle à 2 et définir le statut à 1 une fois le traitement terminé

    Vous pouvez spécifier le nombre de données à mettre à jour à chaque fois
  • Affûtage du trafic (redis implémente les ventes flash)

Utilisez la structure de données de file d'attente

  • lpush/rpush pour mettre les données dans la liste


    lpop/rpop pour supprimer les données de la liste et obtenir la valeur suppriméeExplication détaillée de la mise en œuvre et de lapplication de la file dattente de messages PHP (avec organigramme)

    ltrim Éléments réservés dans la plage spécifiée
  • llen Récupère la longueur de la liste

    lset Définit la valeur de la liste par index
  • lindex Récupère la valeur dans la liste par index

    lrange Récupère les éléments de la plage spécifiée

Le schéma est le suivant

    • Le flux de code est le suivant
    • Le programme flash kill écrit la requête dans redis(uid, time)
    • Vérifiez la longueur de stockage de la liste redis , si plus de 10 sont directement supprimés
    • Lisez les données Redis via une boucle infinie et stockez-les dans la base de données
    • // 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);
          }}
      Copier après la connexion
  • 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é
    Explication détaillée de la mise en œuvre et de lapplication de la file dattente de messages PHP (avec organigramme)

  • . L'idée spécifique et le pseudo code sont les suivants
  •   // 先将商品放入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)
      // 抢购成功
    Copier après la connexion

    • rabbitmq

    • Architecture et principe

    • où P représente le producteur et X est le commutateur (canal), C signifie consommateur

    Simple à utiliser
  // 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();
Copier après la connexion
  // 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();
  }
Copier après la connexion
  • 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!

    Étiquettes associées:
    source:learnku.com
    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
    Tutoriels populaires
    Plus>
    Derniers téléchargements
    Plus>
    effets Web
    Code source du site Web
    Matériel du site Web
    Modèle frontal