Confirmation du message avancé MQ

Veuillez ajouter une description de l'image
Carte de visite personnelle :

Blogueur: Ivrogneᝰ.
Profil personnel: Offrez-vous du vin et utilisez l'énergie du vin pour lutter pour un avenir.
Cet article est inspirant: Quand nous voyageons à trois ensemble, nous devons être mon professeur.

Veuillez ajouter une description de l'image
Ce projet est basé sur Java "SpringCloud Microservice Technology Stack" par le programmeur cheval noir de la station B , SpringCloud+RabbitMQ+Docker+Redis+search+distributed

[SpringCloud+RabbitMQ+Docker+Redis+search+explication détaillée et distribuée du système cours sur la pile technologique des microservices Springcloud | Programmeur Dark Horse Microservices Java] Cliquez pour regarder

2. Fiabilité des messages

De l'envoi d'un message à sa réception par le consommateur, plusieurs processus sont gérés :
Insérer la description de l'image ici

Chacune de ces étapes peut entraîner une perte de message. Les raisons courantes de perte sont les suivantes :

  • Perdu lors de l'envoi :
    • Le message envoyé par le producteur n'est pas remis à l'échange
    • Le message n'atteint pas la file d'attente après avoir atteint l'échange
  • MQ est en panne et la file d'attente perd des messages
  • Après avoir reçu le message, le consommateur plante sans le consommer.

En réponse à ces problèmes, RabbitMQ apporte des solutions :

  • Mécanisme de confirmation du producteur
  • persistance mq
  • Mécanisme de confirmation du consommateur
  • Mécanisme de nouvelle tentative d'échec

Tout d'abord, importez le projet de projet (mq-advanced-demo) fourni par le matériel préalable au cours.

1. Confirmation du message du producteur

RabbitMQ fournit un mécanisme de confirmation d'éditeur pour éviter la perte de message lors de l'envoi à MQ. Ce mécanisme doit attribuer un identifiant unique à chaque message. Une fois le message envoyé à MQ, un résultat sera renvoyé à l'expéditeur, indiquant si le message a été traité avec succès.

Il existe deux manières de renvoyer les résultats :

  • confirmation de l'éditeur, confirmation de l'expéditeur
    • Le message est transmis avec succès au commutateur et un accusé de réception est renvoyé.
    • Le message n'est pas transmis au commutateur et nack est renvoyé.
  • retour éditeur, accusé de réception de l'expéditeur
    • Le message est transmis au commutateur, mais n'est pas acheminé vers la file d'attente. Renvoie ACK et la raison de l’échec du routage.

Avis:

Insérer la description de l'image ici

  1. Modifier le paramètre

Tout d'abord, modifiez l'adresse IP, le nom d'utilisateur, le mot de passe et d'autres configurations de lapinmq dans le fichier application.yml du service éditeur, et ajoutez le contenu suivant :

spring:
  rabbitmq:
    publisher-confirm-type: correlated
    publisher-returns: true
    template:
      mandatory: true

illustrer:

  • publish-confirm-type : Activez la confirmation de l'éditeur. Deux types sont pris en charge ici :
    • simple : Attendez le résultat de la confirmation de manière synchrone jusqu'à l'expiration du délai
    • correlated: Rappel asynchrone, définissez ConfirmCallback, MQ rappellera ce ConfirmCallback lors du renvoi du résultat
  • publish-returns: Activez la fonction de publication-retour, qui est également basée sur le mécanisme de rappel, mais définit ReturnCallback
  • template.mandatory: Définissez la stratégie en cas d'échec du routage des messages. true, appelle ReturnCallback ; false : supprime le message directement
  1. Définir le rappel de retour

每个RabbitTemplate只能配置一个ReturnCallback, il doit donc être configuré lors du chargement du projet :

Modifiez le service éditeur et ajoutez-en un :

package cn.itcast.mq.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
public class CommonConfig implements ApplicationContextAware {
    
    

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    
    
        //获取rabbitTemplate
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
        //设置ReturnCallback
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> {
    
    
            log.error("消息发送失败,应答码:{},原因:{},交换机:{},路由键:{},消息:{}",
                    replyCode, replyText, exchange, routingKey, message);
        });
    }
}
  1. DefineConfirmCallback

ConfirmCallback peut être spécifié lors de l'envoi d'un message, car la logique de chaque traitement métier confirmant le succès ou l'échec n'est pas nécessairement la même.

Dans la classe cn.itcast.mq.spring.SpringAmqpTest du service éditeur, définissez une méthode de test unitaire :

package cn.itcast.mq.spring;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.UUID;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAmqpTest {
    
    
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testSendMessage2SimpleQueue() throws InterruptedException {
    
    
        //消息体
        String message = "hello, spring amqp!";
        //设置唯一ID。封装到CorrelationData中
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        //添加callback
        correlationData.getFuture().addCallback(
                result -> {
    
    
                    if (result.isAck()){
    
    
                        //ack,发送成功
                        log.debug("消息发送交换机成功,ID:{}", correlationData.getId());
                    }else {
    
    
                        //nock,发送失败
                        log.error("消息发送交换机失败,ID:{}", correlationData.getId());
                    }
                },
                ex -> log.error("消息发送队列失败,ID:{},原因:{}", correlationData.getId(), ex.getMessage())
        );
        //发送消息
        rabbitTemplate.convertAndSend("amq.direct", "amq", message, correlationData);
    }
}

Test :
ajoutez l'échange et la file d'attente correspondant au code côté navigateur mq, et définissez la clé de routage du contact. file d'attente
d'échange
Insérer la description de l'image ici

Insérer la description de l'image ici

Résultats clés de routage
Insérer la description de l'image ici
 :
Insérer la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/m0_65144570/article/details/133150243
conseillé
Classement