7. Springboot 2.x intègre RabbitMQ pour réaliser une confirmation d'envoi de message et une confirmation de réception de message pour réaliser une livraison de message à 100%

Springboot2.x intègre RabbitMQ pour réaliser une confirmation d'envoi de message et une confirmation de réception de message pour réaliser une livraison de message à 100%

Préface

  • Comment le message garantit-il un succès de livraison à 100%?
  • Explication détaillée du concept d'idempotence
  • Comment éviter le problème de la consommation répétée de messages pendant la période de pointe lorsque des commandes massives sont générées?
  • Confirmer le message de confirmation, retourner le message de retour

Comment le message garantit-il un succès de livraison à 100%?

1.1 Qu'est-ce qu'une livraison fiable du côté de la production?

  • Garantir le succès du message
  • Assurer la réception réussie des nœuds MQ
  • L'expéditeur reçoit la réponse de confirmation du nœud MQ (Broker)
  • Mécanisme complet de compensation de message

Les trois premières étapes peuvent ne pas garantir la livraison à 100% du message. Alors ajoutez la quatrième étape

La solution du géant de l'Internet BAT / TMD:

  • Base de données de dépôt de message, marquez l'état du message
    Lors de l'envoi d'un message, vous devez conserver le message dans la base de données et définir un statut pour le message (non envoyé, envoyé, arrivé). Lorsque l'état du message change, une modification doit être apportée au message. Effectuez une opération circulaire pour les messages qui ne sont pas arrivés et renvoyez-les. Il y a également une limite de 3 à 5 fois pour le nombre de rotations. Assurez-vous que le message peut être envoyé avec succès.

  • Retard de livraison des messages, deuxième confirmation, contrôle de rappel

Le schéma à adopter dépend de la quantité de services et de messages simultanés.

1.2 Le premier schéma:

Livraison fiable côté production

Par exemple: envoyez un message de commande comme suit.

étape 1: Stockez le message de commande (créez une commande), les données commerciales sont stockées dans la base de données et le message est également stocké dans la base de données. Inconvénients: besoin de persister deux fois. (Statut: 0)
step2: En partant du principe que l'étape 1 est réussie, envoyez un message
Étape 3: Une fois que le courtier a reçu le message, confirmez à notre fin de production. Confirm Listener surveille de manière asynchrone les messages renvoyés par Broker.
étape 4: récupérez le message spécifié et mettez à jour (état = 1), indiquant que le message a été remis avec succès.

étape5: la tâche de synchronisation distribuée obtient l'état du message, s'il est égal à 0, puis récupérez les données.
step6: renvoyer le message
step7: définir la limite de relance 3 fois. Si le message échoue après 3 tentatives, alors (état = 2), le message est considéré comme un échec.

Demander pourquoi ces messages ont échoué peut nécessiter une enquête manuelle.

Supposons que l'étape 2 est exécutée avec succès et que l'étape 3 est due à un flash réseau. Ensuite, confirmez ne recevra jamais le message, nous devons alors définir une règle:
Par exemple: lorsque le message est stocké dans la base de données, définissez une valeur critique timeout = 5min, quand elle dépasse 5min, les données seront capturées.
Ou écrivez une tâche chronométrée pour saisir l'état = 0 messages toutes les 5 minutes. Il peut y avoir un petit problème: le message est envoyé, la tâche chronométrée est juste exécutée et la confirmation n'a pas été reçue, la tâche chronométrée sera exécutée, provoquant l'exécution du message deux fois.
Fonctionnement plus raffiné: limite de tolérance de temporisation des messages. Si la confirmation ne reçoit pas le message dans les 2-3 minutes, il sera renvoyé.

Remarque: face aux applications à petite échelle, des transactions peuvent être ajoutées pour assurer la cohérence des transactions. Cependant, face à une forte concurrence dans les grandes usines, aucune transaction n'est ajoutée, l'épissage de performance des transactions est très sérieux, mais une compensation est faite.

Pour assurer MQ, nous pensons que si le premier type de livraison fiable est approprié dans un contexte de forte concurrence?

Le premier système comprend deux stockages de données, un stockage de données commerciales et un stockage de messages. Il s'agit d'un goulot d'étranglement pour le stockage des données.
En fait, nous n'avons besoin que de stocker l'entreprise.

Retard de livraison des messages, deuxième confirmation, contrôle de rappel

Cette méthode ne garantit pas forcément un succès à 100%, mais elle peut également garantir 99,99% des messages. Si vous rencontrez une situation particulièrement extrême, il vous suffit de compenser manuellement ou de chronométrer des tâches pour le faire.
La deuxième méthode consiste principalement à réduire le fonctionnement de la base de données.

1.2 Le deuxième schéma:

étape 1: une fois le message professionnel stocké avec succès dans la base de données, le premier message est envoyé.
étape 2: De même, une fois le message stocké avec succès dans la base de données, le deuxième message est envoyé et les deux messages sont envoyés en même temps. Le deuxième message est une vérification différée, qui peut être réglée sur 2 min ou 5 min pour retarder l'envoi.
étape 3: le consommateur surveille la file d'attente spécifiée.
étape 4: une fois que le consommateur a traité le message, une nouvelle confirmation d'envoi de message est générée en interne. Livraison au courtier MQ.
étape 5: service de rappel Le service de rappel surveille le courtier MQ. Si le message envoyé par le service en aval est reçu, il peut être déterminé que le message est envoyé avec succès et le message d'exécution est stocké dans la base de données MSG.
Étape 6: Vérifiez les détails pour vérifier et surveiller le message de livraison retardée de l'étape 2. À ce stade, les deux files d'attente de surveillance ne sont pas les mêmes. Après 5 minutes, le service de rappel reçoit le message et vérifie la base de données MSG. Si vous constatez que le message précédent a été remis avec succès, vous n'avez pas besoin de faire autre chose. Si la vérification échoue, Callback compense et envoie activement la communication RPC. Avertissez le producteur en amont de renvoyer le message.

Le but de cela: un stockage DB de moins. L'accent n'est pas mis sur un succès de livraison à 100%, mais sur la performance.

2. Le concept d'idempotence

2.1 Qu'est-ce que l'idempotence?

Idempotent (idempotent, idempotence) est un concept mathématique et informatique couramment trouvé dans l'algèbre abstraite, à savoir f (f (x)) = f (x). En termes simples, le résultat d' une opération exécutée plusieurs fois est cohérent avec le résultat d'une exécution .

  • Nous pouvons apprendre du mécanisme de verrouillage optimiste de la base de données:
  • Par exemple, nous exécutons une instruction SQL pour mettre à jour l'inventaire:
  • METTRE À JOUR T_REPS SET COUNT = COUNT - 1, VERSION = VERSION + 1 WHERE VERSION = 1

Utilisez la méthode d'ajout du numéro de version pour garantir l'idempotence.

2.2 Garantie de la puissance finale du consommateur

Comment éviter le problème de la consommation répétée de messages pendant la période de pointe lorsque des commandes massives sont générées?

Dans le cas d'une concurrence élevée, un grand nombre de messages arrivera à MQ et le consommateur doit surveiller un grand nombre de messages. Dans ce cas, des envois répétés de messages, des flashs de réseau, etc. se produiront inévitablement. Si vous ne faites pas d'idempotence, il y aura une consommation répétée de messages.
-La réalisation de l'idempotence côté consommateur signifie que nos messages ne seront jamais consommés plusieurs fois, même si nous recevons plusieurs messages identiques, ils ne seront exécutés qu'une seule fois.

Regardez les opérations idempotentes traditionnelles des grandes entreprises Internet:
-Unique ID + mécanisme d'empreintes digitales, en utilisant les clés primaires de la base de données pour supprimer les doublons.
-Utiliser l'atomicité de Redis pour atteindre
-Autres technologies pour atteindre l'idempotence

2.2.1 Mécanisme d'identification unique + code d'empreinte digitale

  • ID unique + mécanisme d'empreinte digitale, utilisant la clé primaire de la base de données pour supprimer les doublons.
    Garantir l'unicité
  • SELECT COUNT (1) FROM T_ORDER WHERE ID = ID unique + code d'empreinte digitale
    Si la requête n'existe pas, ajoutez-la. Il n'y a rien à faire et le consommateur n'a pas besoin de consommer des messages.
  • Avantage: simple à mettre en œuvre
  • Inconvénients: goulot d'étranglement des performances pour les écritures de base de données en cas de forte concurrence
  • Solution: suivez l'ID dans la sous-base de données et la sous-table pour effectuer un routage algorithmique afin d'
    allouer la pression de trafic.

2.2.2 Implémentation de la fonctionnalité atomique Redis

L'auto-incrémentation de Redis est la plus simple à utiliser.

  • Problèmes à prendre en compte lors de l'utilisation de Redis pour l'idempotence.
  • Premièrement: avons-nous besoin que les données soient stockées dans la base de données? Si tel est le cas, le problème clé à résoudre est de savoir comment atteindre l'atomicité dans la base de données et le cache?
    L'ajout de transactions ne fonctionne pas. Redis et les transactions de base de données ne sont pas les mêmes, et il n'y a aucune garantie de succès et d'échec simultanés. Avez-vous un meilleur plan?
  • Deuxièmement: comment définir la stratégie de synchronisation du temps si le stockage n'est pas effectué, alors tous sont stockés dans le cache?
    Comment obtenir la stabilité des données mises en cache?

3. Confirmer le message de confirmation

Comprendre le mécanisme de confirmation de message de confirmation:

  • La confirmation du message signifie qu'après que le producteur a livré le message, si le courtier reçoit le message, il nous donnera une réponse au producteur.
  • Le producteur reçoit la réponse pour déterminer si le message est envoyé normalement au Broker.Cette méthode est également la garantie de base pour la livraison fiable du message!

3.1 Mettre en œuvre le message de confirmation de confirmation

spring:
  application:
    name: zoo-plus-rabbitmq
  rabbitmq:
    virtual-host: /
    host: localhost
    port: 5672
    username: guest
    password: guest
    publisher-confirm-type: correlated #必须配置这个才会确认回调

Producteur:

    /**
     * 测试消息确认回调(必须在yml配置publisher-confirm-type: correlated)
     */
    @GetMapping("sendConfirmCallback")
    public Resp sendConfirmCallback() {
    
    
        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
    
    
            System.out.println("ack:" + ack);
            if (!ack) {
    
    
                //可以进行日志记录、异常处理、补偿处理等
                System.out.println("异常处理");
            }else{
    
    
                //更新数据库,可靠性投递机制
            }
        });
        amqpTemplate.convertAndSend("test-queue", "测试ack确认模式");
        return Resp.success("ok", null);
    }

4. Mécanisme de retour des messages

  • Return Listener est utilisé pour traiter certains messages non routables!
  • Notre producteur de message, en spécifiant une clé d'échange et de routage, envoie le message à une certaine file d'attente, puis notre consommateur écoute la file d'attente pour les opérations de traitement de la consommation!
  • Mais dans certains cas, si l'échange actuel n'existe pas ou si la clé de routage spécifiée ne peut pas être acheminée lorsque nous envoyons un message, à ce stade, si nous devons écouter de tels messages inaccessibles, nous devons utiliser Return Listener!

Il existe un élément de configuration clé dans l'API de base:

  • Obligatoire: S'il est vrai, l'auditeur recevra le message indiquant que la route est inaccessible, puis effectuera un traitement ultérieur. S'il est faux, le courtier supprimera automatiquement le message!

4.1 Implémenter le message de confirmation de confirmation

Configuration

spring:
  application:
    name: zoo-plus-rabbitmq
  rabbitmq:
    virtual-host: /
    host: localhost
    port: 5672
    username: guest
    password: guest
    publisher-returns: true #支持发布返回

Code

    /**
     * 启动消息失败返回,比如路由不到队列时触发回调
     * 测试发布回调(必须在yml配置publisher-returns: true)
     */
    @GetMapping("sendReturnCallback")
    public Resp sendReturnCallback() {
        RabbitTemplate.ReturnCallback returnCallback = (message, replyCode, replyText, exchange, routingKey) -> {
            System.out.println("========returnCallback=============");
        };
        rabbitTemplate.setReturnCallback(returnCallback);
        amqpTemplate.convertAndSend("test-", "测试发布回调模式");
        return Resp.success("ok", null);
    }

Adresse source: https://gitee.com/zoo-plus/springboot-learn/tree/2.x/springboot-middleware/rabbitmq

Je suppose que tu aimes

Origine blog.csdn.net/qq_36850813/article/details/104294779
conseillé
Classement