一 什么是死信队列

当一条消息在队列中出现以下三种情况的时候,该消息就会变成一条死信。

  • 消息被拒绝(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 拒绝消息,并且禁止重新入队

  1. 设置yml为手动签收模式
spring:
rabbitmq:
listener:
simple:
acknowledge-mode: manual
  1. 设置拒绝消息并禁止重新入队
Long deliverTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
channel.basicNack(deliverTag,false,false);
  1. 绑定死信队列
@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用到的几个注解

  1. @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 {};
}
  1. @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 {};
}
  1. @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》什么是死信队列的更多相关文章

  1. 关于 RabbitMQ 的 Dead-Letters-Queue “死信队列”

      来自一个队列的消息可以被当做‘死信’,即被重新发布到另外一个“exchange”去,这样的情况有: 消息被拒绝 (basic.reject or basic.nack) 且带 requeue=fa ...

  2. Rabbitmq消费失败死信队列

    Rabbitmq 重消费处理 一 处理流程图: 业务交换机:正常接收发送者,发送过来的消息,交换机类型topic AE交换机: 当业务交换机无法根据指定的routingkey去路由到队列的时候,会全部 ...

  3. RabbitMQ TTL、死信队列

    TTL概念 TTL是Time To Live的缩写,也就是生存时间. RabbitMQ支持消息的过期时间,在消息发送时可以进行指定. RabbitMQ支持队列的过期时间,从消息入队列开始计算,只要超过 ...

  4. RabbitMQ (五):死信队列

    什么是TTL RabbitMQ的TTL全称为Time-To-Live,表示的是消息的有效期.消息如果在队列中一直没有被消费并且存在时间超过了TTL,消息就会变成了"死信" (Dea ...

  5. RabbitMQ死信队列

    关于RabbitMQ死信队列 死信队列 听上去像 消息“死”了     其实也有点这个意思,死信队列  是 当消息在一个队列 因为下列原因: 消息被拒绝(basic.reject/ basic.nac ...

  6. 【MQ中间件】RabbitMQ -- RabbitMQ死信队列及内存监控(4)

    1.RabbitMQ TTL及死信队列 1.1.TTL概述 过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取:过了之后消息将自动被删除.RabbitMQ可以对消息和队列设 ...

  7. RabbitMQ死信队列另类用法之复合死信

    前言 在业务开发过程中,我们常常需要做一些定时任务,这些任务一般用来做监控或者清理任务,比如在订单的业务场景中,用户在创建订单后一段时间内,没有完成支付,系统将自动取消该订单,并将库存返回到商品中,又 ...

  8. rabbitmq实现延时队列(死信队列)

    基于队列和基于消息的TTL TTL是time to live 的简称,顾名思义指的是消息的存活时间.rabbitMq可以从两种维度设置消息过期时间,分别是队列和消息本身. 队列消息过期时间-Per-Q ...

  9. RabbitMQ 死信队列 延时

    package com.hs.services.config; import java.util.HashMap; import java.util.Map; import org.springfra ...

  10. RabbitMQ与.net core(四) 消息的优先级 与 死信队列

    1.消息的优先级 假如现在有个需求,我们需要让一些优先级最高的通知推送到客户端,我们可以使用redis的sortedset,也可以使用我们今天要说的rabbit的消息优先级属性 Producer代码 ...

随机推荐

  1. 数据分析02 /pandas基础

    数据分析02 /pandas基础 目录 数据分析02 /pandas基础 1. pandas简介 2. Series 3. DataFrame 4. 总结: 1. pandas简介 numpy能够帮助 ...

  2. Django 【基础篇】

    前戏 python Web程序 众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端. #!/usr/bin/env python #cod ...

  3. 自动生成和安装requirements.txt依赖

    在查看别人的Python项目时,经常会看到一个requirements.txt文件,里面记录了当前程序的所有依赖包及其精确版本号.这个文件有点类似与Rails的Gemfile.其作用是用来在另一台PC ...

  4. IE9+的树状下拉菜单,支持多选

    //JS核心代码function treeBox(Config){var el=eval(Config.el);var w=Config.width;var h=Config.height;var d ...

  5. rabbitmq+sleuth+zinkip 分布式链路追踪

    我们都知道,微服务之间通过feign传递,在复杂的微服务架构系统中,几乎每一个前端请求都会形成一个复杂的分布式服务调用链路,在每条链路中任何一个依赖服务出现延迟超时或者错误都有可能引起整个请求最后的失 ...

  6. 由一个计数器出发:关于vue使用独立js文件的问题

    最近有个vue项目要用ztree. 然后,我想把一些逻辑提出来作为公共的方法,放到独立的js文件里. ztreeTool.js import $ from 'jquery' export defaul ...

  7. 【真实分享】学习linux!让我工资翻5倍!从月薪3000到年薪18W!只用了六个月!

    月薪3000到年薪18W,我用了六个月时间.从只会皮毛,到一家公司的运维工程师主力,我的故事蛮神奇的,今天和大家分享一下我自己的经历. 我今年26岁,之前做个体,修过电脑,卖过电脑,做过桌面运维,一直 ...

  8. 设计模式:chain of responsibility模式

    目的:弱化发出请求的对象和处理请求对象的之间的关系 理解:每个处理请求的对象仅仅只关注自己能处理的请求,不关系其他请求 优点: 无需一个管理类来匹配所有的请求,更灵活 责任链可以动态的调整 Andor ...

  9. mybatis逆向工程生成java代码和xml配置

    mybatis官方提供了一个逆向工程包,可以针对数据库表自动生成mybatis执行所需要的Pojo.Mapper xml文件.Mapper 接口文件. mybatis-generator有很多种用法: ...

  10. Monster Audio 使用教程(二)效果参数的保存

    点击左上角主菜单按钮,点击[保存]菜单,即可保存当前的所有效果参数. [另存为]菜单,则是把当前参数另存一个名称,然后通过[切换效果]菜单,实现效果的切换.  独立保存单个音轨的效果 点击音轨对应的[ ...