当前位置:网站首页>Quatre schémas de mise en file d'attente des messages pour redis

Quatre schémas de mise en file d'attente des messages pour redis

2022-06-12 01:41:00 Tendresse et manque de bois de chauffage

redisMise en œuvre d'un schéma centralisé de mise en file d'attente des messages:
1、Basé surListDeLPUSHEtBRPOPRéalisation
2、PUB/SUB,Abonnements/Mode de publication
3、Basé surSorted-SetRéalisation
4、Basé surStreamMise en œuvre du type
 

1、Basé surlistListelpushEtbrpopMise en file d'attente des messages

Producteurs,Simulation30Article (s)id,DépôtlistListe
<?php
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$redis->select(0);
$goodsId = 30;
$key = "sec_kill:active:active_1";
// Cycle ajouter des produits
for ($i=1;$i<=$goodsId;$i++){
    $redis->rPush($key,$i);
}

 Consommateurs,Mettre la marchandiseidDelistLa liste sort,Utilisateurs analogiquesid,Un. Une correspondance30C'est exact.,Dépôthash,Il reste2970Le second utilisateur a échoué,Enregistrer une quantité,Et enregistrer le numéro de l'utilisateur défaillant dans la listelist

<?php
// Prétendre être l'identificateur unique de l'utilisateur
$uuid = md5(uniqid('user').time());
// Créer un lienredisObjet
$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$redis->select(0);
$goodsKey = "sec_kill:active:active_1";
$orderKey = "sec_kill:active:order_1";
$failUserNum = "sec_kill:active:fail_user_num";
$failUser = "sec_kill:active:fail_user";
if ($goodsId = $redis->lPop($goodsKey)){
    // Le second a réussi.
    //  Mettre les utilisateurs chanceux dans la collection 
    $redis->hSet($orderKey,$goodsId,$uuid);
    echo "Commande réussie".PHP_EOL;
}else{
    // Échec de second Kill   Nombre d'utilisateurs échoués 
    $redis->incr($failUserNum);
    $redis->rPush($failUser,$uuid);
    echo "Échec de la commande".PHP_EOL;
}

 Logiquement, Il devrait y avoir un auditeur watcher,ÉcouterwatcherDelist, Y a - t - il des biens non consommés? , Si elle n'est pas consommée après la date d'expiration , Doit être stocké dans la liste de production , Recyclage de la consommation ( Blogueurs , Ce paragraphe n'a pas besoin d'être lu. , Écrit par l'auteur , Parce qu'il ne correspond pas au contexte , Ça pourrait vous embrouiller. )

2、redisPublication/Abonnements(PUB/SUB)Mise en file d'attente des messages

(1)Tout d'abord,,Introduction2Concept de groupe

channel:Channel,Tuyauterie,Canal, C'est un passage. , Tous les clients abonnés à ce canal , Vous pouvez recevoir des messages de la chaîne

pattern:Mode,Ou plutôt, Collection de canaux multiples ,( Un peu comme un sentiment régulier ), Abonné au modèle , Tous les messages envoyés par les canaux correspondants , Le client peut recevoir

(2)channelEtpatternPrincipes de mise en œuvre sous - jacents

Quand un client exécutesubscribeLes ordres, Lorsque vous vous abonnez à un ou plusieurs canaux , Ce client établit une relation d'abonnement entre les canaux abonnés .

RedisEnregistrer les relations d'abonnement pour tous les canaux dans l'état du serveurpubsub_channelsDans le dictionnaire, La clé de ce dictionnaire est le canal auquel vous vous abonnez ,La valeur de la clé est une liste liée,Tous les clients qui s'abonnent à ce canal sont enregistrés dans la liste,Niveau inférieurC Principes de mise en oeuvre linguistique :


struct redisServer {
 
    // ...
 
    // Enregistrer les relations d'abonnement pour tous les canaux
    dict *pubsub_channels;
 
    // ...
 
};

Selon que le canal a déjà d'autres abonnés ,L'opération associée est effectuée dans deux cas:

1、 Si le canal a déjà d'autres abonnés ,Alors il estpubsub_channelsIl doit y avoir une liste d'abonnés correspondante dans le Dictionnaire,La seule chose que le programme doit faire est d'ajouter le client à la fin de la liste des abonnés

2、 Si la chaîne n'a pas encore d'abonnés ,Il doit donc n'exister pas avecpubsub_channelsDictionnaire,La procédure commence parpubsub_channelsCréer une clé pour le canal dans le Dictionnaire,Et réglez la valeur de cette clé à une liste de liens vides,Puis ajoutez le client à la liste liée,Devient le premier élément de la liste

 subscribeL'implémentation de la commande peut être décrite avec le pseudocode suivant:

def subscribe(*all_input_channels):
 
    # Traverser tous les canaux entrés
    for channel in all_input_channels:
 
        # Si channel N'existe pas pubsub_channels Dictionnaire(Il n'y a pas d'abonnés)
        # Ajouter au dictionnaire channel Clé,Et définissez sa valeur à une liste de liens vides
        if channel not in server.pubsub_channels:
            server.pubsub_channels[channel] = []
 
        # Ajouter un abonné à la fin de la liste des chaînes correspondant au canal
        server.pubsub_channels[channel].append(client)

Déclaration: Cette partie s'inspire de 《RabbitMQChef lapin》, Cet article fait un résumé personnel dans le but d'une communication amicale , Pas de commerce ,Lien original:https://blog.csdn.net/hebtu666/article/details/114827837

 unsubscribeLes ordres etsubscribe L'ordre est le contraire. , .Lorsqu'un client se désabonne d'un canal ou d'un canal ,Le serveur va partir depubsub_channels Dissociation d'un client d'un canal désabonnement :

1、Le programme sera basé sur le nom du canal auquel vous vous abonnez, In pubsub_channels Liste des abonnés pour le canal trouvé dans le dictionnaire, Ensuite, supprimez les informations du client de désabonnement de la liste des abonnés

2、Si, après avoir supprimé le client de désabonnement, La liste des abonnés du canal est devenue une liste vide, Donc ça veut dire qu'il n'y a plus d'abonnés à ce canal, Le programme sera lancé à partir de pubsub_channels Supprimer la clé correspondant au canal dans le Dictionnaire

 unsubscribeL'implémentation de la commande peut être décrite avec le pseudocode suivant:


def unsubscribe(*all_input_channels):
 
    # Traverser tous les canaux à désabonner
    for channel in all_input_channels:
 
        # Supprimer les clients non abonnés de la liste des abonnés
        server.pubsub_channels[channel].remove(client)
 
        # Si la chaîne n'a plus d'abonnés(La liste des abonnés est vide)
        # Alors retirez le canal du Dictionnaire
        if len(server.pubsub_channels[channel]) == 0:
            server.pubsub_channels.remove(channel)

Section mode:

Le serveur a une relation d'abonné pour tous les modes pubsub_PatternsDans l'attribut


struct redisServer {
 
    // Enregistrer les relations d'abonnement pour tous les canaux
    list *pubsub_patterns;
 
};

pubsub_PatternsLa propriété est une liste liée, Chaque noeud est un modèle d'abonnement , Mode enregistré dans le noeud ,Dans le noeudclient La propriété enregistre les clients en mode abonnement


typedef struct pubsubPattern{
    //Clients en mode abonnement
    redisClient *client;
    //Mode d'abonnement
    robj *pattern;
}pubsubPattern;

Chaque fois que le client exécutePSUBSCRIBE Lorsque cette commande s'abonne à un ou plusieurs modes , Le serveur fait ce qui suit pour chaque mode auquel il est abonné :

1)Créer un nouveaupubsubPatternStructure, Définissez les deux propriétés

2) Ajouter un nouveau noeud à pubsub_patternsQueue

Mise en œuvre du pseudocode:


def osubscribe(*all_input_patterns):
    # Traverser tous les modes d'entrée 
    # Notez le modèle auquel vous vous abonnez et le client correspondant 
    pubsubPattern=create()
    pubsubPattern.client=client
    pubsubPattern.pattern=pattern
 
    #Insérer à la fin de la liste
    server.pub_patterns.append(pubsubPattern)

Commande de désabonnement du mode PUNSUBSCRIBE- Oui.PSUBSCRIBEContre - opération de

Le serveur localisera et supprimera les schémas qui ont été désactivés


def osubscribe(*all_input_patterns):
    # Traverser tous les modes de désabonnement 
    for pattern in all_input_patterns:
        #Traverser chaque noeud
        for pubsubPattern in server.pubsub_patterns:
            # Si le client et le mode sont les mêmes 
            if client==pubsubPattern.client:
                if pattern==pubsubPattern.pattern:
                    #Supprimer
                    server.pub_patterns.remove(pubsubPattern)

Envoyer un message:

Quand un client exécutePUBLISH<channel> <message> Lorsque la commande envoie un message au canal ,Le serveur a besoin de:

1) Envoyer un message à tous les abonnés de ce canal

C'est comme ça. pubsub_channels Le dictionnaire trouve la liste de liens de ce canal , C'est - à - dire la liste d'abonnement ,Et envoyer un message

2)Envoyer un message à, Contient tous les abonnés dans tous les modes de ce canal

C'est comme ça. pubsub_patterns Trouver le mode contenant ce canal , Et envoyer des messages aux clients qui s'y abonnent .


Voir les informations d'abonnement:

redis2.8 Ajouter trois commandes , Pour voir des informations sur les canaux et les modes .

PUBLISH CHANNELS[pattern] Pour retourner le canal auquel le serveur est actuellement abonné ,patternPeut écrire mais pas écrire, Voir tout sans écrire , Sinon, voir avec pattern Canal correspondant

Cette sous - commande passe par pubsub_channelsDictionnaire implémenté.

PUBLISH NUMSUB[CHANNEL-1 CHANNEL-2.....]Nombre d'abonnés retournés à ces canaux

Cette sous - commande passe par pubsub_channelsDictionnaire, Voir la longueur de la liste correspondante .

PUBLISH NUMPAT Renvoie le nombre de modes souscrits

Cette sous - commande est retournée pubsub_patterns La longueur de .

En résumé,PUBSUB Les trois sous - commandes de la commande sont lues par pubsub_channels Dictionnaires et pubsub_patterns Informations dans la liste liée.

Pratique personnelle :

Quatre clients A、B、C、D,A Le client s'est abonné au canal news.it     D Le client s'est abonné au canal news.et     BC Mode d'abonnement du client   news.[ie]t, Entre parenthèses ici ,ie Ordre des parties de deux lettres

ALes ordres:subscribe news.it

BLes ordres:psubscribe news.[ie]t

CLes ordres:psubscribe news.[ie]t

DLes ordres:subscribe news.et

  Quand nous publions un message :publish news.it  'She is not boy!'        Voir l'image:

  Lorsque nous publions un message d'abonnement :publish news.et 'He is not girls! And  this boy is very cute!'

 Note::De gauche à droite,De haut en bas, Client à la fois   ABCD    Le mode visible est similaire à la régularité , Combien de canaux correspondent , Quand ces canaux envoient des messages , Clients abonnés à ce canal , Et les clients qui s'abonnent aux modèles pertinents ,Vous recevrez un message.

 En bas:AdoptionPHPCode, Mettre en file d'attente des messages autant que possible

Ce n'est pas fini aujourd'hui, Regardez ce blogueur ,SuivantredisExplication, Fini demain.

原网站

版权声明
本文为[Tendresse et manque de bois de chauffage]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/163/202206120136483291.html