Registro diario: SpringBoot integra RabbitMQ Sección 5 (letra muerta)

1. Letra muerta

1. ¿Qué es la letra muerta?

Cuando un mensaje en una cola cumple una de las siguientes condiciones, puede convertirse en letra muerta:

  1. El mensaje TTL expiró;
  2. La cola alcanza la longitud máxima (la cola está llena, no se pueden agregar más datos a RabbitMQ);
  3. El mensaje se rechaza (basic.reject o basic.nack) y el mensaje establece requeue=false (no se vuelve a poner en cola);

Por defecto, los mensajes fallidos se descartan directamente
inserte la descripción de la imagen aquí

2. El fracaso en el consumo se convierte en letra muerta

Política de reintento:

  1. RejectAndDontRequeueRecoverer: una vez agotados los reintentos, rechaza directamente y pierde el mensaje. es la estrategia de procesamiento predeterminada
  2. ImmediateRequeueMessageRecoverer: una vez agotados los reintentos, se devuelve nack y el mensaje se vuelve a poner en cola
  3. RepublishMessageRecoverer: una vez agotados los reintentos, entrega el mensaje de error al intercambio especificado

En la estrategia de reintento fallido, el RejectAndDontRequeueRecoverer predeterminado enviará un rechazo a RabbitMQ después de que se agote el número de reintentos locales, y el mensaje se convierte en letra muerta y se descarta. (Si utiliza la estrategia RepublishMessageRecoverer, recuerde desactivarla; de lo contrario, el mensaje puede arrojarse a la cola vinculada a la estrategia)

Podemos agregar un interruptor de mensajes no entregados a la cola y vincular una cola de mensajes no entregados al interruptor de mensajes no entregados. De esta manera, una vez que el mensaje se convierte en letra muerta, no se descartará, sino que finalmente se entregará al conmutador de mensajes no entregados y se enrutará a la cola de mensajes no entregados vinculada al conmutador de mensajes no entregados.

3. Definir conmutadores de mensajes fallidos y colas de mensajes fallidos.

Los conmutadores y colas de mensajes no entregados también son conmutadores y colas comunes, por lo que se definen de la siguiente manera:

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


//死信交换机和死信队列也是普通的交换机和队列
@Configuration
public class DeadQueueConfig {
    
    

    //定义死信交换机
    @Bean
    public DirectExchange deadLetterExchange() {
    
    
        return ExchangeBuilder.directExchange("dead.letter.exchange").build();
    }


    //定义死信队列
    @Bean
    public Queue deadLetterQueue() {
    
    
        return new Queue("dead.letter.queue",true,false,false);
    }

    //交换机和队列绑定
    @Bean
    public Binding deadLetterQueueBinding(Queue deadLetterQueue, DirectExchange deadLetterExchange) {
    
    
        return BindingBuilder.bind(deadLetterQueue).to(deadLetterExchange).with("dl");
    }
}

4. Cómo vincular colas y conmutadores de mensajes no entregados

Vincular el intercambio de mensajes no entregados y la cola de mensajes no entregados

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;


@Configuration
public class TestDeadQueueConfig {
    
    

    @Bean
    public DirectExchange testDeadLetterExchangeExchange() {
    
    
        return ExchangeBuilder.directExchange("test.dead.letter.exchange").build();
    }



    @Bean
    public Queue testDeadLetterQueue() {
    
    


     return QueueBuilder.durable("test.dead.letter.queue")
             //test.dead.letter.queue队列绑定死信交换机
             .deadLetterExchange("dead.letter.exchange")
             //死信交换机和死信队列绑定 routingKey = dl
             .deadLetterRoutingKey("dl")
             .build();

        /*Map<String, Object> args = new HashMap();
        // DLX(死信交换机)
        args.put("x-dead-letter-exchange", "死信队列交换机的名称");
        // DLK(死信路由key)
        args.put("x-dead-letter-routing-key", "死信消息路由的routingKey");
        // TTL(time-to-live存活时间)
        args.put("x-message-ttl", 10000);
        return new Queue("test.dead.letter.queue",true,false,false,args);*/

    }

    //交换机和队列绑定
    @Bean
    public Binding testDeadLetterQueueBinding(Queue testDeadLetterQueue, DirectExchange testDeadLetterExchangeExchange) {
    
    
        return BindingBuilder.bind(testDeadLetterQueue).to(testDeadLetterExchangeExchange).with("test.dead.letter");
    }
}

inserte la descripción de la imagen aquí

5. Después de que el mensaje falla, se entrega a letra muerta.

productor simulado

import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class DeadQueueTest {
    
    

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    void test(){
    
    
       //模拟生产者
       rabbitTemplate.convertAndSend("test.dead.letter.exchange","test.dead.letter","进行死信测试");


    }
}

consumidor simulado


import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class DeadQueueListener {
    
    

    @RabbitListener(queues = "test.dead.letter.queue")
    public void testDeadLetterQueueMsg(String msg){
    
    

        System.out.println("test.dead.letter.queue收到消息:"+msg);

        //模拟:处理消息中出现了异常
        int i = 1/0;

        System.out.println("消息处理完毕!");
    }
}

inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí
El mensaje se entregó correctamente a la cola de mensajes no entregados.

6. El tiempo de espera del mensaje se agota y se entrega como letra muerta.

De forma predeterminada, el mensaje no caducará. Si no establece ningún parámetro relacionado con la caducidad del mensaje, el mensaje no caducará. Incluso si el mensaje no se consume, siempre se almacenará en la cola.

Si se configura TTL, el mensaje se eliminará automáticamente una vez superado este tiempo.

  1. Establecido por propiedades de la cola: todos los mensajes en la cola tienen el mismo tiempo de vencimiento
  2. Configure el mensaje individualmente: cada mensaje TTL puede ser diferente
  3. Utilice ambos métodos al mismo tiempo, el tiempo de vencimiento está sujeto al valor más pequeño.

1. Tiempo de espera de la cola de demostración TTL, entregado a la cola de mensajes no entregados

Definir una cola y establecer un tiempo de vencimiento para ella

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TTLQueueConfig {
    
    


    @Bean
    public DirectExchange ttlExchange(){
    
    
        return ExchangeBuilder.directExchange("ttl.exchange").build();
    }

    //定时队列,设置过期时间,并且绑定死信交换机
    @Bean
    public Queue ttlQueue(){
    
    
        return QueueBuilder.durable("ttl.queue")
                //设置队列的超时时间为10s
                .ttl(10*1000)
                //给队列设置死信交换机,名称为dead.letter.exchange 设置投递死信时的RoutingKey为dl
                .deadLetterExchange("dead.letter.exchange")
                .deadLetterRoutingKey("dl")
                .build();
    }

    @Bean
    public Binding ttlBinding(Queue ttlQueue, DirectExchange ttlExchange){
    
    
        return BindingBuilder.bind(ttlQueue).to(ttlExchange).with("test.ttl.queue");
    }


}

productor simulado

import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class TTLQueueTest {
    
    

    @Autowired
    private RabbitTemplate rabbitTemplate;

    //模拟生产者
    @Test
    public void test(){
    
    
        rabbitTemplate.convertAndSend("ttl.exchange","test.ttl.queue","这个队列10秒后过期,然后到死信队列");
    }


}

Después de iniciar el servicio
inserte la descripción de la imagen aquí
llama al productor.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

2. Tiempo de espera TTL del mensaje de demostración, entregado a la cola de mensajes no entregados

Intercambio de colas y mensajes fallidos con tiempo de espera de cola de prueba

import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalTime;

@SpringBootTest
public class TTLQueueTest {
    
    

    @Autowired
    private RabbitTemplate rabbitTemplate;

    //模拟生产者
    @Test
    public void testTTLMessage() {
    
    
        String msgStr = "消息TTL demo,发送时间是:" + LocalTime.now();

        Message message = MessageBuilder
                .withBody(msgStr.getBytes())
                //设置消息TTL为5秒
                .setExpiration("5000")
                .build();

        //发送消息时:
        //  如果消息和队列都设置了TTL,则哪个TTL短,哪个生效
        //  如果消息和队列只设置了一个TTL,则直接以设置的为准
        rabbitTemplate.convertAndSend("ttl.exchange", "test.ttl.queue", message);
    }



}

Escenario de uso: el usuario realiza un pedido y, si no paga en 15 minutos, el pedido se cancela automáticamente y así sucesivamente.

Supongo que te gusta

Origin blog.csdn.net/qq407995680/article/details/132142406
Recomendado
Clasificación