死信队列:DLX,dead-letter-exchange

利用dlx,当消息在一个队列中变成死信(dead message)之后,它能被重新publish到另一个exchange,这个exchange就是dlx

消息变成死信的原因有:

1.消息被拒绝(basic.reject / basic.nack)并且reQueue=false

2.消息TTL过期

3.队列达到最大长度了

1.声明死信队列,交换机等。

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 RabbitMQConfig { //死信队里s @Bean("deadLetterExchange")
public Exchange deadLetterExchange() {
return ExchangeBuilder.directExchange("DL_EXCHANGE").durable(true).build();
} @Bean("deadLetterQueue")
public Queue deadLetterQueue() {
Map<String, Object> args = new HashMap<>(2);
// x-dead-letter-exchange 声明 死信交换机
args.put("x-dead-letter-exchange", "DL_EXCHANGE");
// x-dead-letter-routing-key 声明 死信路由键
args.put("x-dead-letter-routing-key", "KEY_R");
return QueueBuilder.durable("DL_QUEUE").withArguments(args).build();
} @Bean("redirectQueue")
public Queue redirectQueue() {
return QueueBuilder.durable("REDIRECT_QUEUE").build();
} /**
* 死信路由通过 DL_KEY 绑定键绑定到死信队列上.
*
* @return the binding
*/
@Bean
public Binding deadLetterBinding() {
return new Binding("DL_QUEUE", Binding.DestinationType.QUEUE, "DL_EXCHANGE", "DL_KEY", null); } /**
* 死信路由通过 KEY_R 绑定键绑定到死信队列上.
*
* @return the binding
*/
@Bean
public Binding redirectBinding() {
return new Binding("REDIRECT_QUEUE", Binding.DestinationType.QUEUE, "DL_EXCHANGE", "KEY_R", null);
} //死信队里e
}

当DL_KEY 对应的队列中存在死信时,rabbitMQ就会自动的将这个消息重新发布到设置的exchange上去,进而被路由到KEY_R对应的队列。


2.生产者:

import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import java.util.UUID; /**
* Created by Jim on 2018/11/24.
*/
@Component
public class DLQueue { @Autowired
private RabbitTemplate rabbitTemplate; public void sendMsg(String content) {
CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
MessagePostProcessor messagePostProcessor = message -> {
MessageProperties messageProperties = message.getMessageProperties();
// 设置编码
messageProperties.setContentEncoding("utf-8");
// 设置过期时间10*1000毫秒
messageProperties.setExpiration("5000");
return message;
};
rabbitTemplate.convertAndSend("DL_EXCHANGE", "DL_KEY", content, messagePostProcessor);
}
}

这里设置了5000的过期时间,一旦消息到了过期时间还没被正常消费,就会变成死信。

3.DL_KEY 对应的消费者:

@Component
public class DlxMessageReceiver1 {
@RabbitHandler
@RabbitListener(queues = "DL_QUEUE")//方法级注解
public void process(String msg, Channel channel, Message message){
System.out.println("死信DL_KEY收到 : " + msg );
System.out.println(1/0); } }

为了测试,这里注意不要捕获异常,捕获了异常的话,不会进入死信。

4.KEY_R对应的消费者

@Component
public class DlxMessageReceiver {
@RabbitHandler
@RabbitListener(queues = "REDIRECT_QUEUE")
public void process(String msg, Channel channel, Message message)throws Exception {
System.out.println("死信KEY_R: " +msg);
channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
}
}

在上面2中我们设置了5秒的过期时间,下面我们看看是不是5秒过后就变成死信。

第一次消费失败的时间是:2018-11-24 20:57:11.949

死信DL_KEY  : 123
2018-11-24 20:57:11.949 WARN 616 --- [cTaskExecutor-1] s.a.r.l.ConditionalRejectingErrorHandler : Execution of Rabbit message listener failed.

最后一次消费失败的时间是:2018-11-24 20:57:13.871

死信DL_KEY : 123
2018-11-24 20:57:13.871 WARN 616 --- [cTaskExecutor-1] s.a.r.l.ConditionalRejectingErrorHandler : Execution of Rabbit message listener failed.
死信KEY_R: 123

由结果来看,好像没到5秒就过期了,我也不是很明白,有空再研究。

rabbimq之死信队列的更多相关文章

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

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

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

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

  3. MSMQ 队列消息和死信队列

    日志消息 日志队列可以保存你操作过的消息的备份.它的好处是,一但发现前面的操作失败,可以从日志队列中重新创建出原先的消息对象,然后再进行操作. 例如,向远方发送一个消息对象,然后对方返回一个失败的确认 ...

  4. Spring Boot系列——死信队列

    在说死信队列之前,我们先介绍下为什么需要用死信队列. 如果想直接了解死信对接,直接跳入下文的"死信队列"部分即可. ack机制和requeue-rejected属性 我们还是基于上 ...

  5. RabbitMQ 死信队列 延时

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

  6. ActiveMQ_5死信队列

    activemq死信队列 DLQ-死信队列(Dead Letter Queue)用来保存处理失败或者过期的消息. 出现以下情况时,消息会被redelivered: A transacted sessi ...

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

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

  8. MQ中间件死信队列深度不断增加问题解决案例

    感谢作者: http://www.wo81.com/tec/mid/mq/2014-04-14/94.html  MQ中间件死信队列深度不断增加问题解决案例 ❞ ☜ ☞ 作者:彭新 日期:2014-0 ...

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

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

随机推荐

  1. 列表的操作,元组,range; enumerate

    一.列表: 1. 什么是列表 列表是一个可变的数据类型 ,列表由[]来表示, 每一项元素使用逗号隔开. 列表什么都能装. 能装对象的对象. 列表可以装大量的数据 2. 列表的索引和切片 列表和字符串一 ...

  2. Swift和Objective C关于字符串的一个小特性

    一.Unicode的一个小特性 首先,Unicode规定了许多code point,每一个code point表示一个字符.如\u0033表示字符"3",\u864e表示字符&qu ...

  3. 低版本php对json的处理

    由于低版本php(php5以下)没有json_encode和json_decode 所以有下面函数实现 function json_encode($data) { switch ($type = ge ...

  4. Maven依赖的JAR包下载慢?赶紧看过来

    相信许多JAVA开发者在日常工作中时常会碰到这种情况,那就是编译Maven工程时,工程所依赖的jar包文件下载非常慢,甚至经常出现下载不成功的问题,今天,小编就给大家讲讲如何提升Maven依赖包的下载 ...

  5. 2018 ICPC Asia Jakarta Regional Contest

    题目传送门 题号 A B C D E F G H I J K L 状态 Ο . . Ο . . Ø Ø Ø Ø . Ο Ο:当场 Ø:已补 .  :  待补 A. Edit Distance Thin ...

  6. am335x uboot启动流程分析

    基本指令含义 .globl _start .globl指示告诉汇编器,_start这个符号要被链接器用到,所以要在目标文件的符号表中标记它是一个全局符号 b,bl b是不带返回的跳转  bl带返回的跳 ...

  7. android面试注意点

    Java 基础知识 面向对象的基本思想 Object类相关:Object类的几个关键函数.String涉及到的常量池概念,序列化 & 反序列化. 重要关键字:final.static. 内部类 ...

  8. c# 小票打印

    c# 在进行小票打印时大致有三种方法. 1. 使用水晶报表进行打印.可以参考:https://www.cnblogs.com/aitong/p/10717786.html 2. 在 PrintDocu ...

  9. 计算机网络透明网桥算法时间戳c++

    要交CG的兄弟们别抄啊,撞上了严nan谁都不会放过的 好久没写博客了,这次是老师布置的作业,做出来一种,觉得写得很不好,第一种方法把情况都写死在代码里了. 上代码 #include<iostre ...

  10. selenium 之Ran 0 tests in 0.000s

    from selenium import webdriverfrom time import ctime,sleepimport unittestclass TestLogin(unittest.Te ...