rabbitmq死信队列详解(亲手实践)

news/2024/11/23 5:33:27/

目录

1 概念

2 成为死信队列的条件

2.1 队列指定长度 

2.2  消息ttl时间

2.3 消费者拒收消息


1 概念

死信队列:死信队列其实和普通的队列一样,只不过里面存放的消息都是普通队列过期没有消费的。所以,接收没有及时被消费消息的队列为死信队列。

2 成为死信队列的条件

以下条件只要满足一条,即可以成为死信队列。

  1. 队列长度满了:排在前面的消息会被拒收或者进入死信交换机
  2. 消息的ttl时间到了:消息超时未被消费
  3. 消息被拒收了:手动拒绝消息

一个队列设置了队列长度或者过期时间或被拒收,并且设置了死信队列的交换机和死信的路由key。那么消息满足条件就会进入死信队列。

例如:

@Bean("queueB")
public Queue queueB(){Map<String, Object> arguments  = new HashMap<>();//设置死信交换机arguments.put("x-dead-letter-exchange",Y_DEAD_LETTER_XCHANGE);//设置死信RoutingKeyarguments.put("x-dead-letter-routing-key","YD");//设置ttlarguments.put("x-message-ttl",40000);return QueueBuilder.durable(QUEUE_B).withArguments(arguments).build();
}

以上只是声明了一个普通队列queueB,然后在该队列设置了过期时间40s,和死信交换机和死信路由key。

注意:死信队列就是一个普通的队列,只不过声明普通队列的时候指定了死信交换机,二者才产生了联系

2.1 队列指定长度 

配置相关队列和交换机

注意:声明一个队列分为3步(声明交换机、声明队列、将队列和交换机路由绑定)

package com.liubujun.rabbitmqspringbootdemo.config;import com.rabbitmq.client.AMQP;
import com.sun.javafx.collections.MappingChange;
import jdk.nashorn.internal.objects.NativeUint8Array;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.Exchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;/*** @Author: liubujun* @Date: 2023/6/3 16:15*/@Component
public class DeadQueueConfig {//队列public static final String FORMAL_QUEUE = "formal_queue";public static final String DEAD_QUEUE = "dead_queue";//交换机public static final String FORMAL_EXCHANGE = "formal_exchange";public static final String DEAD_EXCHANGE = "dead_exchaneg";//路由keypublic static final String FORMAL_ROUNTE_KEY = "formal_rounte_key";public static final String DEAD_ROUNTE_KEY = "dead_route_key";/*** 普通队列交换机声明* 交换机类型:topic:处理路由键,按模式匹配,向符合规则的队列投递消息* name 交换机名称* durable 是否持久化* autoDelete 是否删除* arguments 用于设置其他参数* @return*/@Beanpublic Exchange getFormalExchange(){return new TopicExchange(FORMAL_EXCHANGE,true,false,null);}/*** 声明普通队列,并设置与死信队列联系* name 队列名称* durable 是否持久化* exclusive 是否排外 如果是排外的,该队列 仅对首次声明它的连接(Connection)可见,是该Connection私有的,* 类似于加锁,并在连接断开connection.close()时自动删除* autoDelete 是否删除* arguments 用于设置其他参数* @return*/@Beanpublic Queue getFormalQueue(){Map<String, Object> map = new HashMap<>();//设置队列最大长度map.put("x-max-length",5);//设置死信队列交换机map.put("x-dead-letter-exchange",DEAD_EXCHANGE);//设置死信队列路由keymap.put("x-dead-letter-routing-key",DEAD_ROUNTE_KEY);return new Queue(FORMAL_QUEUE,true,false,false,map);}/*** 将普通队列和交换机绑定* destination:目标队列或交换器* destinationType:DesdinationType指出目标是交换器还是对列* exchange:交换机* routingKey:路由key* arguments:参数设置* @return*/@Beanpublic Binding bingFormalQueue(){return new Binding(FORMAL_QUEUE, Binding.DestinationType.QUEUE,FORMAL_EXCHANGE,FORMAL_ROUNTE_KEY,null);}/*** 声明死信队列交换机* @return*/@Beanpublic Exchange getDeadExchange(){return new TopicExchange(DEAD_EXCHANGE,true,false,null);}/*** 声明死信队列* @return*/@Beanpublic Queue getDeadQueue(){return new Queue(DEAD_QUEUE,true,false,false, null);}/*** 将死信队列和交换机绑定* @return*/@Beanpublic Binding bingDeadQueue(){return new Binding(DEAD_QUEUE, Binding.DestinationType.QUEUE,DEAD_EXCHANGE,DEAD_ROUNTE_KEY,null);}}

生产者:发送6条消息,看rabbitmq中队列变化

    @GetMapping("/sendMessageTtl/{message}")public void sendMessageTtl(@PathVariable String message){log.info("当前时间发送:{},发送5条消息给两个TTL队列:{}",new Date().toString(),message);for (int i = 0; i < 6; i++) {rabbitTemplate.convertAndSend(DeadQueueConfig.FORMAL_EXCHANGE,DeadQueueConfig.FORMAL_ROUNTE_KEY,message);}}

rabbitmq控制台:

普通队列有5条消息,而死信队列有1条消息。

因为在声明普通队列的时候,已经说明了队列最大长度为5,那么多余的消息就会根据配置的参数找到对应的交换机进而找到对应的路由,然后路由到对应的队列(死信队列) 。

2.2  消息ttl时间

继续沿用上面的配置,只不过修改下普通队列的参数。

    @Beanpublic Queue getFormalQueue(){Map<String, Object> map = new HashMap<>();//设置队列超时时间map.put("x-message-ttl",5000);//设置死信队列交换机map.put("x-dead-letter-exchange",DEAD_EXCHANGE);//设置死信队列路由keymap.put("x-dead-letter-routing-key",DEAD_ROUNTE_KEY);return new Queue(FORMAL_QUEUE,true,false,false,map);}

发送消息:

可以发现,发送给普通队列的消息,超时没有被消费,都进入到了死信队列中。 

2.3 消费者拒收消息

沿用上面的配置,并在声明普通队列的时候去掉消息的过期时间。

注意:需要在rabbitmq控制台删除队列,不然项目启动会报错。

添加消费者:

@Slf4j
@Component
public class DeadQueueConsumer {/*** 监听死信队列*/
//    @RabbitListener(queues = DeadQueueConfig.DEAD_QUEUE)
//    public void listenDeadQueue(Message message, Channel channel){
//    log.info("接收到死信队列消息:{}",message.getBody());
//    }/*** 监听普通队列*/@RabbitListener(queues = "formal_queue")public void listenFormalQueue(Message message, Channel channel) throws IOException {log.info("接收到普通队列消息:{}",message.getBody());long deliveryTag = message.getMessageProperties().getDeliveryTag();//拒绝消息channel.basicReject(deliveryTag,false);}
}

rabbitmq控制台结果: 

消息在消费者端被拒收后,直接被放进了死信队列。


http://www.ppmy.cn/news/274918.html

相关文章

定积分求含无穷大的式子的和

前置知识 黎曼积分的概念牛顿-莱布尼茨公式 介绍 根据定积分的概念&#xff0c;可以得出 ∫ a b f ( x ) d x lim ⁡ n → ∞ 1 n ∑ i 1 n f ( a b − a n i ) \int_a^bf(x)dx\lim\limits_{n\to \infty}\dfrac 1n\sum\limits_{i1}^{n}f(a\dfrac{b-a}{n}i) ∫ab​f(x)dxn…

【深入理解Linux内核锁】一、内核锁的由来

我的圈子&#xff1a; 高级工程师聚集地 我是董哥&#xff0c;高级嵌入式软件开发工程师&#xff0c;从事嵌入式Linux驱动开发和系统开发&#xff0c;曾就职于世界500强公司&#xff01; 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; …

互联网智慧旅游云平台项目解决方案

后台回复“0916”&#xff0c;可下载该PPT。 资料已经上传至「智能交通技术」知识星球&#xff0c;加入星球后可下载。 欢迎加入智能交通技术群&#xff01; 联系方式&#xff1a;微信号18515441838

万豪参加进博会品牌+目的地策略继续深耕中国市场;加利福尼亚乐高乐园和法拉利推出互动式景点项目 | 全球旅报...

万豪国际第四次参与进博会 品牌目的地策略继续深耕中国市场。新品牌AC明年亮相。进入9个新目的地&#xff0c;助力国内游。MOXY签约数量稳步增长&#xff0c;布局年轻化市场。 爱彼迎柏思齐&#xff1a;旅行回归实为旅行变革&#xff0c;稳中迎变才能引领复苏。爱彼迎发布了202…

阿维塔陪伴用户悦己而行,与用户共创悦己生活

在2023上海国际车展上&#xff0c;阿维塔举办品牌升级发布会&#xff0c;而此次它的主题是“情感智能&#xff0c;悦己同行”。按照当前阿维塔的发展战略而言&#xff0c;在今年下半年&#xff0c;它将进一步深化与华为之间的战略合作&#xff0c;在2024年年底之前&#xff0c;…

乐玩差旅:专注垂直目的地市场的妙知旅

吴琼 随着从用户社区、机票、酒店类切入旅游市场机会越来越小&#xff0c;目的地市场资源的整合成了在线旅游角逐的新大陆&#xff1b;另一方面讲&#xff0c;ADS&#xff08;指定旅游目的地协议&#xff09;框架的宽松化也为出境自助游释放了更多的空间。妙知旅即专注于垂直目…

如何打造高品质的文旅夜游项目

文旅夜游是一个相关性高、渗透性强、易融合、驱动力大的综合性产业。充分发挥文旅对各行各业的渗透作用&#xff0c;使第三产业能够有效推动第一产业和第二产业的发展&#xff0c;对城市经济建设具有重要意义。夜游是目前最热门的旅游形式&#xff0c;创造夜游产品&#xff0c;…

旅游出行 APP 哪家强?

随着人们的生活水平的提高&#xff0c;旅游出行已经在越来越多人的年中计划里。据相关数据统计&#xff0c;2014年国民旅游意愿强烈&#xff0c;有超过99%的人计划出游&#xff0c;51%的人选择出游3次或以上&#xff1b;95%的消费者会增加旅游预算或保持不变&#xff0c;1/3的人…