File d'attente de messages et file d'attente de messages différés

Scénarios d'application

1. Pic de matières premières

Les demandes d'utilisateurs explosives se produisent dans un court laps de temps. Si des mesures appropriées ne sont pas prises, le serveur sera submergé et le problème de délai de réponse entraînera de fausses morts de service et, au pire, le serveur tombera directement en panne.

À ce stade, une file d'attente de messages est ajoutée. Une fois que le serveur a reçu toutes les demandes de l'utilisateur, il écrit d'abord toutes ces demandes dans la file d'attente de messages, puis les met en file d'attente pour traitement, de sorte qu'il n'entraîne pas le traitement de plusieurs demandes à en même temps; si la longueur de la file d'attente des messages dépasse le nombre maximal pouvant être transporté, nous pouvons abandonner la demande de l'utilisateur actuel et informer l'utilisateur frontal de "la page a mal tourné, veuillez actualiser" et d'autres invites, de sorte que il y aura une meilleure expérience interactive.

2. Découplage du système

Après avoir utilisé la file d'attente de messages, nous pouvons modulariser les fonctions métiers du système et réaliser le découplage du système.

Les exigences des produits changent constamment. Pour le moment, nous avons pensé à utiliser des files d'attente de messages pour réaliser le découplage du système. La réalisation de chaque fonction est indépendante, et seul un commutateur d'abonnement ou de désabonnement est nécessaire. Lorsque vous avez besoin d'ajouter une fonction, vous il suffit de l'ouvrir. Il vous suffit de vous abonner à la file d'attente "Informations utilisateur complètes". Si vous ne l'utilisez pas dans deux jours, désactivez simplement le commutateur d'abonnement.

3. Journalisation

Pratique générale: demande de l'utilisateur - (traitement de la demande de l'utilisateur, journal d'enregistrement (à compléter)) - réponse à la réception

Utiliser la file d'attente des messages: demande de l'utilisateur traitant la demande de l'utilisateur - mettre dans la file d'attente des messages, répondre directement à la réception

Intergiciel de messagerie-RabbitMQ

À l'heure actuelle, les middlewares MQ (Message Queue) les plus couramment utilisés sur le marché sont RabbitMQ, Kafka, RocketMQ. S'il s'agit d'une file d'attente de messages légère, vous pouvez utiliser la file d'attente de messages fournie par Redis.

Concepts importants

Producteur: le créateur du message, responsable de la création et de la transmission des données vers le serveur

Consommateur: le destinataire du message, utilisé pour traiter les données et confirmer le message

Agent: service RabbitMQ lui-même, il est utilisé pour jouer le rôle d '"express", car il ne produit pas de messages par lui-même, mais joue uniquement le rôle d' "express", stockant et transmettant temporairement des messages.

Organigramme de traitement

Insérez la description de l'image ici

avantage:

Prend en charge la persistance, RabbitMQ prend en charge la fonction de persistance du disque pour garantir que les messages ne seront pas perdus;
haute concurrence, RabbitMQ utilise le langage de développement Erlang, Erlang est un langage développé pour les échanges téléphoniques, il est né avec un anneau lumineux parallèle élevé et des fonctionnalités de haute disponibilité;
distribution de support En raison de l'implémentation du langage Erlang, le déploiement du cluster RabbitMQ est également très simple. Il vous suffit de démarrer chaque nœud et d'utiliser --link pour ajouter le nœud au cluster, et RabbitMQ prend en charge la sélection de maître automatique et la reprise après sinistre automatique;
Prise en charge de plusieurs langues , tels que Java, .NET, PHP, Python, JavaScript, Ruby, Go, etc.;
confirmation de message de support, confirmation de consommation de message de support (ack) pour s'assurer que chaque message peut être consommé normalement;
il prend en charge de nombreux plug-ins, tels que en tant que pages Web Pour les plug-ins de gestion des messages de la console, les plug-ins de délai de message, etc., RabbitMQ a de nombreux plug-ins et est très pratique à utiliser.

Type de message:

mode direct (type par défaut), ce mode est un mode d'envoi individuel, c'est-à-dire qu'un message ne sera envoyé qu'à un seul consommateur; le
mode en-têtes vous permet de faire correspondre l'en-tête du message au lieu de la clé de routage ( RoutingKey), en plus L'utilisation des en-têtes et du direct est exactement la même, mais comme les performances de correspondance des en-têtes sont très faibles, il n'est presque jamais utilisé; le
mode de diffusion, qui est une méthode de multidiffusion, distribuera un message à tous les abonnés;
mode sujet, qui est le modèle d'abonnement au sujet, les caractères génériques (#, *) peuvent correspondre à un ou plusieurs messages. Je peux utiliser "cn.mq. #" pour faire correspondre plusieurs messages avec le préfixe "cn.mq.xxx", pour par exemple, il peut correspondre à "cn. mq.rabbit", "cn.mq.kafka" et à d'autres messages.

File d'attente de messages personnalisés

Nous pouvons utiliser Queue pour implémenter des files d'attente de messages. Les files d'attente peuvent être divisées en gros dans les trois catégories suivantes:

Deque

Il s'agit d'une sous-classe de Queue et d'une classe supplémentaire de Queue. La tête et la queue prennent en charge l'insertion et l'acquisition d'éléments

La file d'attente de blocage fait référence à l'opération d'élément (ajout ou suppression), si elle échoue, elle bloquera l'attente d'exécution. Par exemple, lors de l'ajout d'un élément, si l'élément de file d'attente est plein, la file d'attente se bloquera et attendra qu'il y ait un espace à insérer; la
file d'attente non bloquante, contrairement à la file d'attente bloquante, retournera directement le résultat de l'opération, au lieu de bloquer l'opération d'attente, deque appartient également à la file d'attente non bloquante.

Bloc de code de file d'attente de messages personnalisé

import java.util.LinkedList;
import java.util.Queue;

public class CustomQueue {
    
    
    private static Queue<String> queue=new LinkedList<>();

    public static void main(String[] args) {
    
    
        producer();
        consumer();
    }
    //生产者
    public static void producer(){
    
    
        queue.add("first-message");
        queue.add("second-message");
        queue.add("third-message");
    }
    //消费者
    public static void consumer(){
    
    
        while (!queue.isEmpty())
        {
    
    
            System.out.println(queue.poll());
        }
    }
}

premier message
deuxième message
troisième message

File d'attente de retard personnalisée

import lombok.Getter;
import lombok.Setter;

import java.text.DateFormat;
import java.util.Date;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class CustomDelayQueue {
    
    
    private static DelayQueue queue=new DelayQueue();

    public static void main(String[] args) throws InterruptedException {
    
    
        producer();
        consumer();
    }
    //生产者
    public static void producer(){
    
    
        queue.add(new MyDelay(3000,"first-message"));
        queue.add(new MyDelay(1000,"second-message"));

    }
    //消费者
    public static void consumer() throws InterruptedException {
    
    
        System.out.println("开始执行时间:"+DateFormat.getDateTimeInstance().format(new Date()));
        while (!queue.isEmpty())
        {
    
    
            System.out.println(queue.take());
        }
        System.out.println("结束执行时间:"+DateFormat.getDateTimeInstance().format(new Date()));
    }
    //

    static class MyDelay implements Delayed{
    
    
        long delayTime=System.currentTimeMillis();

        @Getter
        @Setter
        private String msg;

        public MyDelay(long delayTime,String msg)
        {
    
    
            this.delayTime=(this.delayTime+delayTime);
            this.msg=msg;
        }

        @Override
        public long getDelay(TimeUnit unit) {
    
    
            return unit.convert(delayTime-System.currentTimeMillis(),TimeUnit.MILLISECONDS);
        }

        @Override
        public int compareTo(Delayed o) {
    
    
           if(this.getDelay(TimeUnit.MILLISECONDS)>o.getDelay(TimeUnit.MILLISECONDS))
               return 1;
           else if(this.getDelay(TimeUnit.MILLISECONDS)<o.getDelay(TimeUnit.MILLISECONDS))
               return -1;
           else return 0;
        }

        @Override
        public String toString() {
    
    
            return this.msg;
        }
    }
}

Heure de début d'exécution: 2020-12-28 19:41:20
deuxième message Heure de fin d'exécution du
premier message
: 2020-12-28 19:41:23

Je suppose que tu aimes

Origine blog.csdn.net/tangshuai96/article/details/111874370
conseillé
Classement