springboot整合rabbitMQ系列5 死信列队3种情况演示1 basic.nack 并且不再重新投递 requeue=false 和 2 ttl消息 3 达到队列最大长度 三种情况

关于死信队列的描述,可查看博文 
rabbitmq死信队列 用rabbitmq web控制台创建交换机,队列,绑定关系,发送TTL超时消息 来做演示_rabbitmq 控制台 添加死信队列-CSDN博客

1 application.yml配置文件

server:
  port: 8021
spring:
  #给项目来个名字
  application:
    name: rabbitmq-test
  #配置rabbitMq 服务器
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: need
    password: 123456
    #虚拟host 可以不设置,使用server默认host
    virtual-host: /testhost

    listener:
      simple:
        acknowledge-mode: manual #手动ACK
      direct:
        acknowledge-mode: manual #手动ACK

2 创建交换机,队列,绑定等,注意看createZhengChangQueue() 方法,创建后的效果图,也可以看上面的博文

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import java.util.HashMap;

@Configuration
public class ExchangeQueueBindingConfig {

    //自动创建就是靠他
    //解决循环依赖
    @Lazy
    @Autowired
    RabbitAdmin rabbitAdmin;

    //死信队列
    @Bean
    public Queue createShiXinQueue() {
        return new Queue("shixin_queue", true);
    }

    //死信交换机
    @Bean
    public DirectExchange createShiXinExchange() {
        return new DirectExchange("shixin_exchange", true, false);
    }

    //死信交换机 死信队列 绑定
    @Bean
    public Binding createShiXinBinding() {
        return BindingBuilder.bind(createShiXinQueue()).to(createShiXinExchange()).with("shixin");
    }

    //正常队列,这里要设置死信交换机,关键所在
    @Bean
    public Queue createZhengChangQueue() {
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("x-dead-letter-exchange", "shixin_exchange");
        map.put("x-dead-letter-routing-key", "shixin");
        
        //故意设置成500,演示 消息满以后,会到死信队列中
        map.put("x-max-length",500);
        return new Queue("zhengchang_queue", true, false, false, map);
    }

    //正常交换机
    @Bean
    public TopicExchange createZhengChangExchange() {
        return new TopicExchange("zhengchang_exchange", true, false);
    }

    //正常交换机 正常队列 绑定
    @Bean
    public Binding createZhengChangBinding() {
        return BindingBuilder.bind(createZhengChangQueue()).to(createZhengChangExchange()).with("chongqing.#");
    }

    //创建初始化RabbitAdmin对象
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        // 只有设置为 true,spring 才会加载 RabbitAdmin 这个类
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }

    //创建交换机和对列
    @Bean
    public void createExchangeQueue() {
        //死信
        rabbitAdmin.declareExchange(createShiXinExchange());
        rabbitAdmin.declareQueue(createShiXinQueue());
        //正常
        rabbitAdmin.declareExchange(createZhengChangExchange());
        rabbitAdmin.declareQueue(createZhengChangQueue());
    }
}

演示发送TTL超时消息,并不要有消费者去消费,过期后就会到死信队列

import cn.huawei.rabbitmqtest1.pojo.User;
import com.alibaba.fastjson.JSON;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
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 java.nio.charset.StandardCharsets;
import java.util.UUID;

@SpringBootTest
public class Test_1 {
    @Autowired
    RabbitTemplate rabbitTemplate;  //使用RabbitTemplate,这提供了接收/发送等等方法

    @Test
    void fangfa1() {
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setExpiration("9000"); // 设置过期时间,单位:毫秒

        for (int i = 1; i < 10; i++) {

            messageProperties.setMessageId(i+"");

            User user = new User(i + "", "小明 " + i);
            //  这个参数是用来做消息的唯一标识
            //发布消息时使用,存储在消息的headers中
            CorrelationData correlationData = new CorrelationData(i+"");

            Message message = new Message(JSON.toJSONString(user).getBytes(StandardCharsets.UTF_8), messageProperties);

            rabbitTemplate.convertAndSend("zhengchang_exchange", "chongqing.news", message, correlationData);
        }
    }
}

一定要手动ack,演示 故意乱输信息(文字等),会出错,进而走到 basic.nack 并且不再重新投递 requeue=false,就会到死信队列

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.io.IOException;

@Component
public class Test_2 {

    //监听的队列名称
    @RabbitListener(queues = "zhengchang_queue")
    /**
     * 注意:后4个参数,需要生产者发送消息时加上,否则为报错,注解里添加 required=false 或 删除参数
     */
    public void process(Message message,
                        Channel channel,
                        @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag,
                        @Header(AmqpHeaders.MESSAGE_ID) String messageId,
                        @Header(AmqpHeaders.CONSUMER_TAG) String consumerTag,
                        CorrelationData correlationData) throws IOException {

        //long deliveryTag = message.getMessageProperties().getDeliveryTag();
        //或 
        //@Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag

        try {
            String msgbody = new String(message.getBody());
            //1.接收转换消息
            System.out.println("消费者 1 收到消息  : " + msgbody + " 编号: " + deliveryTag);

            //2. 处理业务逻辑
            System.out.println("处理业务逻辑...");
            //模拟出现错误
            System.out.println(500 / Double.valueOf(msgbody));

            //3. 手动签收
            channel.basicAck(deliveryTag, true);
        } catch (Exception e) {
            //4.拒绝签收
            /*
            第三个参数:requeue:重回队列。如果设置为true,则消息重新回到queue,broker会重新发送该消息给消费端
            这里要演示发到死信队列,就设置为false
             */
            channel.basicNack(deliveryTag, true, false);
            //channel.basicReject(deliveryTag,false);
        }
    }
}

演示 达到最大队列长度,并不要有消费者去消费,多的消息也会到列信队列
注意看第二步故意设成500,而这里故意调成505,多的几条就会到死信队列中
另外如果发送a,b,c,d,e,f  ,而到死信中的是 a,b,c,就是先发送的消息会弄到死信中

import cn.huawei.rabbitmqtest1.pojo.User;
import com.alibaba.fastjson.JSON;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
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 java.nio.charset.StandardCharsets;
import java.util.UUID;

@SpringBootTest
public class Test_3 {
    @Autowired
    RabbitTemplate rabbitTemplate;  //使用RabbitTemplate,这提供了接收/发送等等方法

    @Test
    void fangfa3() {
        MessageProperties messageProperties = new MessageProperties();
        for (int i = 1; i < 505; i++) {

            messageProperties.setMessageId(i+"");

            User user = new User(i + "", "小明 " + i);
            //  这个参数是用来做消息的唯一标识
            //发布消息时使用,存储在消息的headers中
            CorrelationData correlationData = new CorrelationData(i+"");

            Message message = new Message(JSON.toJSONString(user).getBytes(StandardCharsets.UTF_8),messageProperties);

            rabbitTemplate.convertAndSend("zhengchang_exchange", "chongqing.news", message, correlationData);
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Spring Boot中配置死信队列(Dead Letter Queue),您可以按照以下步骤进行操作: 1. 添加RabbitMQ依赖:在您的Spring Boot项目的pom.xml文件中,添加RabbitMQ依赖。例如,使用以下Maven依赖项: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 2. 配置RabbitMQ连接信息:在application.properties或application.yml文件中,配置RabbitMQ的连接信息,例如: ```properties spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest ``` 3. 创建交换机队列:使用RabbitAdmin或通过注解方式,在您的代码中创建交换机队列。例如,可以使用@Bean注解创建一个RabbitAdmin bean,并在其上使用@PostConstruct注解来创建交换机队列。 ```java @Bean public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) { return new RabbitAdmin(connectionFactory); } @PostConstruct public void setupQueues() { rabbitAdmin().declareExchange(new DirectExchange("myExchange")); rabbitAdmin().declareQueue(new Queue("myQueue")); rabbitAdmin().declareBinding(new Binding("myQueue", Binding.DestinationType.QUEUE, "myExchange", "myRoutingKey", null)); } ``` 4. 配置死信队列:创建一个专用的队列来作为死信队列,并将其与原始队列绑定。您可以在队列声明时设置x-dead-letter-exchange和x-dead-letter-routing-key参数来指定死信队列交换机和路由键。 ```java @PostConstruct public void setupQueues() { rabbitAdmin().declareExchange(new DirectExchange("myExchange")); rabbitAdmin().declareQueue(new Queue("myQueue", false, false, false, new HashMap<String, Object>() {{ put("x-dead-letter-exchange", "dlxExchange"); put("x-dead-letter-routing-key", "dlxRoutingKey");

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值