RabbitMQ中的死信队列(Dead Letter Exchanges)详解

 更新时间:2023年12月12日 09:29:54   作者:warybee  
这篇文章主要介绍了RabbitMQ中的死信队列(Dead Letter Exchanges)详解,当RabbitMQ出现死信,可能会导致业务逻辑错误,比如下订单后修改库存操作,在下单后因为某种原因,发送的消息未被签收,这时库存数据会出现不一致,需要的朋友可以参考下

RabbitMQ死信队列

1. 介绍

当消息在一个队列中变为死信后,它被重新发送到另一个Exchange。

2. 在什么情况下会出现死信

  • 消息未被签收,在消费端使用了 basic.reject 或 basic.nack ,并且requeue设置为false
  • 消息过期(TTL)
  • 消息队列达到了最大长度

3. 实际应用

当RabbitMQ出现死信,可能会导致业务逻辑错误,比如下订单后修改库存操作,在下单后因为某种原因,发送的消息未被签收,这时库存数据会出现不一致。

有死信队列之后我们就可以监听死信队列,来处理业务逻辑。

3.1 死信队列设置

声明队列,添加参数x-dead-letter-exchange

Map<String, Object> agruments = new HashMap<String, Object>();
agruments.put("x-dead-letter-exchange", "dlx.exchange");
//这个agruments属性,要设置到声明队列上
channel.queueDeclare(queueName, true, false, false, agruments);

死信队列,是一个普通的Exchange和queue,需要设置死信Exchange和queue,并进行绑定

/要进行死信队列的声明:
		channel.exchangeDeclare("dlx.exchange", "topic", true, false, null);
		channel.queueDeclare("dlx.queue", true, false, false, null);
		//可以匹配任意routeKey
		channel.queueBind("dlx.queue", "dlx.exchange", "#");

4 代码实现

生产端

public static void main(String[] args) throws Exception {
		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost("127.0.0.1");
		connectionFactory.setPort(5672);
		connectionFactory.setVirtualHost("/");
		Connection connection = connectionFactory.newConnection();
		Channel channel = connection.createChannel();
		String exchange = "test_dlx_exchange";
		String routingKey = "dlx.test";
		String msg = "RabbitMQ DLX Message test";
		for(int i =0; i<1; i ++){
			AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
					.deliveryMode(2)
					.contentEncoding("UTF-8")
					.expiration("10000") //过期时间为1秒
					.build();
			channel.basicPublish(exchange, routingKey, true, properties, msg.getBytes());
		}
	}

消费端

public static void main(String[] args) throws Exception {
		ConnectionFactory connectionFactory = new ConnectionFactory();
		connectionFactory.setHost("192.168.11.76");
		connectionFactory.setPort(5672);
		connectionFactory.setVirtualHost("/");
		Connection connection = connectionFactory.newConnection();
		Channel channel = connection.createChannel();
		// 这就是一个普通的交换机 和 队列 以及路由
		String exchangeName = "test_dlx_exchange";
		String routingKey = "dlx.#";
		String queueName = "test_dlx_queue";
		channel.exchangeDeclare(exchangeName, "topic", true, false, null);
		Map<String, Object> agruments = new HashMap<String, Object>();
		agruments.put("x-dead-letter-exchange", "dlx.exchange");
		//这个agruments属性,要设置到声明队列上
		channel.queueDeclare(queueName, true, false, false, agruments);
		channel.queueBind(queueName, exchangeName, routingKey);
		//要进行死信队列的声明:
		channel.exchangeDeclare("dlx.exchange", "topic", true, false, null);
		channel.queueDeclare("dlx.queue", true, false, false, null);
		//可以匹配任意routeKey
		channel.queueBind("dlx.queue", "dlx.exchange", "#");
	   channel.basicConsume(queueName, true, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    System.out.println("接收到消息::"+new String(body));
                }
            });
	}

运行以上代码,在交换机(Exchange)中会多出一个名为dlx.exchange 类型为topic的交换机,队列中也有一个dlx.queue 队列。

到此这篇关于RabbitMQ中的死信队列(Dead Letter Exchanges)详解的文章就介绍到这了,更多相关RabbitMQ死信队列内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • maven解决依赖冲突的三种解决方法

    maven解决依赖冲突的三种解决方法

    依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成了包版本冲突,本文主要介绍了maven解决依赖冲突的三种解决方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • idea maven项目启动项目不编译target 文件的问题及解决方法

    idea maven项目启动项目不编译target 文件的问题及解决方法

    代码编辑器中无编译错误,通过maven 的clean 、compile、package进行各种操作也都没问题,但是单击绿色箭头运行(默认会先执行IDE本身的Build操作)却报:程序包xxx不存在,这篇文章主要介绍了解决idea maven项目启动项目不编译target文件问题,需要的朋友可以参考下
    2023-05-05
  • 最新IntelliJ IDEA 2020版本的安装教程详解

    最新IntelliJ IDEA 2020版本的安装教程详解

    这篇文章主要介绍了最新IntelliJ IDEA 2020版本的安装教程详解,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • 在Linux上搭建一个Java部署环境的详细步骤

    在Linux上搭建一个Java部署环境的详细步骤

    这篇文章主要介绍了在Linux上搭建一个Java部署环境,安装jdk有很多种方式,但是我们这里推荐的是使用yum直接安装openjdk,本文给大家介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • SpringBoot使用SSE进行实时通知前端的实现代码

    SpringBoot使用SSE进行实时通知前端的实现代码

    这篇文章主要介绍了SpringBoot使用SSE进行实时通知前端,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • mybatis-plus报错net.sf.jsqlparser.statement.select.SelectBody的问题解决

    mybatis-plus报错net.sf.jsqlparser.statement.select.SelectBody的

    本文主要介绍了mybatis-plus报错net.sf.jsqlparser.statement.select.SelectBody的问题解决,具有一定的参考价值,感兴趣的可以了解一下
    2024-08-08
  • Spring元注解@HttpExchange声明式调用HTTP

    Spring元注解@HttpExchange声明式调用HTTP

    这篇文章主要介绍了Spring元注解@HttpExchange声明式调用HTTP,Spring Framework6和Spring Boot3引入了声明式HTTP客户端@HttpExchange,通过接口注解简化REST API调用,核心注解包括@GetExchange、@PostExchange等对应HTTP方法,支持路径参数和请求体,需要的朋友可以参考下
    2025-10-10
  • Java中的interrupt、interrupted和isInterrupted方法区别详解

    Java中的interrupt、interrupted和isInterrupted方法区别详解

    这篇文章主要介绍了Java中的interrupt、interrupted和isInterrupted方法区别详解,interrupt用于中断线程,调用该方法的线程的状态将会被设置为中断状态,线程中断仅仅是设置线程的中断状态位,并不会停止线程,需要用户自己去监视线程的状态并作出处理,需要的朋友可以参考下
    2023-12-12
  • MyBatis图文并茂讲解注解开发一对一查询

    MyBatis图文并茂讲解注解开发一对一查询

    这篇文章主要介绍了SpringBoot中Mybatis注解一对一查询的实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • 在SpringBoot中记录用户操作日志功能

    在SpringBoot中记录用户操作日志功能

    在Web应用程序开发中,记录用户操作日志是一项非常重要的任务,它可以帮助我们追踪用户行为,分析系统状况,以及审计系统的安全性,本文将介绍如何在SpringBoot框架中实现用户操作日志的记录功能,感兴趣的朋友一起看看吧
    2024-12-12

最新评论