《RabbitMQ》什么是死信队列
一 什么是死信队列
当一条消息在队列中出现以下三种情况的时候,该消息就会变成一条死信。
- 消息被拒绝(basic.reject / basic.nack),并且requeue = false
- 消息TTL过期
- 队列达到最大长度
当消息在一个队列中变成一个死信之后,如果配置了死信队列,它将被重新publish到死信交换机,死信交换机将死信投递到一个队列上,这个队列就是死信队列。
二 实现死信队列
2.1 原理图

2.2 创建消费者
创建一个消费者,绑定消费队列及死信交换机,交换机默认为direct模型,死信交换机也是,arguments绑定死信交换机和key。(注解支持的具体参数文末会附上)
public class DirectConsumer {
    @RabbitListener(bindings = {
            @QueueBinding(value = @Queue(value = "javatrip",arguments =
                    {@Argument(name="x-dead-letter-exchange",value = "deadExchange"),
                     @Argument(name="x-dead-letter-routing-key",value = "deadKey")
                    }),
                    exchange = @Exchange(value="javatripDirect"),
                    key = {"info","error","warning"}
            )
    })
public void receive1(String message, @Headers Map<String,Object> headers, Channel channel)throws Exception{
    System.out.println("消费者1"+message);
}
2.3 创建生产者
public void publishMessage(String message){
    rabbitTemplate.setMandatory(true);
    rabbitTemplate.convertAndSend("javatripDirect","info",message);
}
三 造成死信的三种情况
3.1 拒绝消息,并且禁止重新入队
- 设置yml为手动签收模式
spring:
  rabbitmq:
    listener:
      simple:
        acknowledge-mode: manual
- 设置拒绝消息并禁止重新入队
Long deliverTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
channel.basicNack(deliverTag,false,false);
- 绑定死信队列
@RabbitListener(bindings = {
    @QueueBinding(
        value = @Queue(value = "javatripDead"),
        exchange = @Exchange(value = "deadExchange"),
        key = "deadKey"
    )
})
public void receive2(String message){
    System.out.println("我是一条死信:"+message);
}
3.2 消息TTL过期
绑定业务队列的时候,增加消息的过期时长,当消息过期后,消息将被转发到死信队列中。
@RabbitListener(bindings = {
            @QueueBinding(value = @Queue(value = "javatrip",arguments =
                    {@Argument(name="x-dead-letter-exchange",value = "deadExchange"),
                     @Argument(name="x-dead-letter-routing-key",value = "deadKey"),
                     @Argument(name = "x-message-ttl",value = "3000")
                    }),
                    exchange = @Exchange(value="javatripDirect"),
                    key = {"info","error","warning"}
            )
    })
public void receive1(String message, @Headers Map<String,Object> headers, Channel channel)throws Exception{
    System.out.println("消费者1"+message);
}
3.3 队列达到最大长度
设置消息队列长度,当队列中的消息达到最大长度后,继续发送消息,消息将被转发到死信队列中。
@RabbitListener(bindings = {
            @QueueBinding(value = @Queue(value = "javatrip",arguments =
                    {@Argument(name="x-dead-letter-exchange",value = "deadExchange"),
                     @Argument(name="x-dead-letter-routing-key",value = "deadKey"),
                     @Argument(name = "x-max-length",value = "3")
                    }),
                    exchange = @Exchange(value="javatripDirect"),
                    key = {"info","error","warning"}
            )
    })
public void receive1(String message, @Headers Map<String,Object> headers, Channel channel)throws Exception{
    System.out.println("消费者1"+message);
}
四 Spring Boot整合RabbitMQ用到的几个注解
- @QueueBinding作用就是将队列和交换机进行绑定,主要有以下三个参数:
@Target({})
@Retention(RetentionPolicy.RUNTIME)
public @interface QueueBinding {
	/**
	 * @return the queue.
	 */
	Queue value();
	/**
	 * @return the exchange.
	 */
	Exchange exchange();
	/**
	 * @return the routing key or pattern for the binding.
	 * Multiple elements will result in multiple bindings.
	 */
	String[] key() default {};
}
- @Queue是声明队列及队列的一些属性,主要参数如下:
@Target({})
@Retention(RetentionPolicy.RUNTIME)
public @interface Queue {
	/**
	 * @return the queue name or "" for a generated queue name (default).
	 */
	@AliasFor("name")
	String value() default "";
	/**
	 * @return the queue name or "" for a generated queue name (default).
	 * @since 2.0
	 */
	@AliasFor("value")
	String name() default "";
	/**
	 * 是否持久化
	 */
	String durable() default "";
	/**
	 * 是否独享、排外的.
	 */
	String exclusive() default "";
	/**
	 * 是否自动删除;
	 */
	String autoDelete() default "";
	/**
	 * 队列的其他属性参数
	 * (1)x-message-ttl:消息的过期时间,单位:毫秒;
         *(2)x-expires:队列过期时间,队列在多长时间未被访问将被删除,单位:毫秒;
         *(3)x-max-length:队列最大长度,超过该最大值,则将从队列头部开始删除消息;
         *(4)x-max-length-bytes:队列消息内容占用最大空间,受限于内存大小,超过该阈值则从队列头部开始删除消息;
         *(5)x-overflow:设置队列溢出行为。这决定了当达到队列的最大长度时消息会发生什么。有效值是drop-head、reject-publish或reject-publish-dlx。仲裁队列类型仅支持drop-head;
         *(6)x-dead-letter-exchange:死信交换器名称,过期或被删除(因队列长度超长或因空间超出阈值)的消息可指定发送到该交换器中;
         *(7)x-dead-letter-routing-key:死信消息路由键,在消息发送到死信交换器时会使用该路由键,如果不设置,则使用消息的原来的路由键值
         *(8)x-single-active-consumer:表示队列是否是单一活动消费者,true时,注册的消费组内只有一个消费者消费消息,其他被忽略,false时消息循环分发给所有消费者(默认false)
         *(9)x-max-priority:队列要支持的最大优先级数;如果未设置,队列将不支持消息优先级;
         *(10)x-queue-mode(Lazy mode):将队列设置为延迟模式,在磁盘上保留尽可能多的消息,以减少RAM的使用;如果未设置,队列将保留内存缓存以尽可能快地传递消息;
         *(11)x-queue-master-locator:在集群模式下设置镜像队列的主节点信息。
	 */
	Argument[] arguments() default {};
}
- @Exchange是声明交换及交换机的一些属性,
@Target({})
@Retention(RetentionPolicy.RUNTIME)
public @interface Exchange {
	String TRUE = "true";
	String FALSE = "false";
	/**
	 * @return the exchange name.
	 */
	@AliasFor("name")
	String value() default "";
	/**
	 * @return the exchange name.
	 * @since 2.0
	 */
	@AliasFor("value")
	String name() default "";
	/**
	 * 交换机类型,默认DIRECT
	 */
	String type() default ExchangeTypes.DIRECT;
	/**
	 * 是否持久化
	 */
	String durable() default TRUE;
	/**
	 * 是否自动删除
	 */
	String autoDelete() default FALSE;
	/**
	 * @return the arguments to apply when declaring this exchange.
	 * @since 1.6
	 */
	Argument[] arguments() default {};
}

《RabbitMQ》什么是死信队列的更多相关文章
- 关于 RabbitMQ 的 Dead-Letters-Queue “死信队列”
		来自一个队列的消息可以被当做‘死信’,即被重新发布到另外一个“exchange”去,这样的情况有: 消息被拒绝 (basic.reject or basic.nack) 且带 requeue=fa ... 
- Rabbitmq消费失败死信队列
		Rabbitmq 重消费处理 一 处理流程图: 业务交换机:正常接收发送者,发送过来的消息,交换机类型topic AE交换机: 当业务交换机无法根据指定的routingkey去路由到队列的时候,会全部 ... 
- RabbitMQ TTL、死信队列
		TTL概念 TTL是Time To Live的缩写,也就是生存时间. RabbitMQ支持消息的过期时间,在消息发送时可以进行指定. RabbitMQ支持队列的过期时间,从消息入队列开始计算,只要超过 ... 
- RabbitMQ   (五):死信队列
		什么是TTL RabbitMQ的TTL全称为Time-To-Live,表示的是消息的有效期.消息如果在队列中一直没有被消费并且存在时间超过了TTL,消息就会变成了"死信" (Dea ... 
- RabbitMQ死信队列
		关于RabbitMQ死信队列 死信队列 听上去像 消息“死”了 其实也有点这个意思,死信队列 是 当消息在一个队列 因为下列原因: 消息被拒绝(basic.reject/ basic.nac ... 
- 【MQ中间件】RabbitMQ -- RabbitMQ死信队列及内存监控(4)
		1.RabbitMQ TTL及死信队列 1.1.TTL概述 过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取:过了之后消息将自动被删除.RabbitMQ可以对消息和队列设 ... 
- RabbitMQ死信队列另类用法之复合死信
		前言 在业务开发过程中,我们常常需要做一些定时任务,这些任务一般用来做监控或者清理任务,比如在订单的业务场景中,用户在创建订单后一段时间内,没有完成支付,系统将自动取消该订单,并将库存返回到商品中,又 ... 
- rabbitmq实现延时队列(死信队列)
		基于队列和基于消息的TTL TTL是time to live 的简称,顾名思义指的是消息的存活时间.rabbitMq可以从两种维度设置消息过期时间,分别是队列和消息本身. 队列消息过期时间-Per-Q ... 
- RabbitMQ  死信队列 延时
		package com.hs.services.config; import java.util.HashMap; import java.util.Map; import org.springfra ... 
- RabbitMQ与.net core(四) 消息的优先级 与 死信队列
		1.消息的优先级 假如现在有个需求,我们需要让一些优先级最高的通知推送到客户端,我们可以使用redis的sortedset,也可以使用我们今天要说的rabbit的消息优先级属性 Producer代码 ... 
随机推荐
- Hello!GitHub 好用好玩值得收藏的开源项目集合~
			这是我许久以来从各处发现的极佳开源项目,希望分享给大家~ 如果帮到你了,给我个赞好嘛 编程语言类 ️learn-go-with-tests(通过单元测试学Go) GitHub地址:https://gi ... 
- 事件循环 event loop 究竟是什么
			事件循环 event loop 究竟是什么 一些概念 浏览器运行时是多进程,从任务管理器或者活动监视器上可以验证. 打开新标签页和增加一个插件都会增加一个进程,如下图:  浏览器渲染进程是多线程,包 ... 
- CondenseNet:可学习分组卷积,原作对DenseNet的轻量化改造 | CVPR 2018
			CondenseNet特点在于可学习分组卷积的提出,结合训练过程进行剪枝,不仅能准确地剪枝,还能继续训练,使网络权重更平滑,是个很不错的工作 来源:晓飞的算法工程笔记 公众号 论文:Neural ... 
- JVM——内存区域:运行时数据区域详解
			关注微信公众号:CodingTechWork,一起学习进步. 引言 我们经常会被问到一个问题是Java和C++有何区别?我们除了能回答一个是面向对象.一个是面向过程编程以外,我们还会从底层内存管理 ... 
- 利用宝塔和rainloop搭建咱的邮箱
			需要咱准备的东东:一枚域名.服务器需根据情况开放25.110.143.465.993端口.宝塔邮局管理器.rainloop.LNMP或者LAMP. 搭建步骤: 1.安装宝塔邮局管理器: 2.设置宝塔邮 ... 
- Java实现简单的增删改查操作
			需求分析:通过数组 ,完成 对学生信息的 管理 (增删改查)创建1个 学生类创建1个 CRUD的类 – 学生管理类 并测试 在这个程序中我只运用了两个类进行操作 package com.hopu.de ... 
- 阿里云的maven仓库
			自从开源中国的maven仓库挂了之后就一直在用国外的仓库,慢得想要砸电脑的心都有了.如果你和我一样受够了国外maven仓库的龟速下载?快试试阿里云提供的maven仓库,从此不在浪费生命…… 仓库地址: ... 
- [leetcode/lintcode 题解] Amazon面试题:连接棒材的最低费用
			为了装修新房,你需要加工一些长度为正整数的棒材 sticks. 如果要将长度分别为 X 和 Y 的两根棒材连接在一起,你需要支付 X + Y 的费用. 由于施工需要,你必须将所有棒材连接成一根. 返回 ... 
- 01 . RPC简介原理及用Go实现一个简单的RCP
			RPC简介 本地过程调用 // 正常情况下程序的执行和调用情况.例如有如下go语言代码: package main import "fmt" func main() { var a ... 
- 2018年5月15日临下班前找的一个读取assets下数据库的例子
			网页 https://blog.csdn.net/li12412414/article/details/51958774 @Override protected void onCreate(Bun ... 
