1、什么是死信

死信产生主要来自于两个过程角色

  • 来自于消费者端
  • 来自于queue

产生死信的三种情况:

  • 如果queue中的消息被消费者接收, 但是消费者拒绝消费(消费者执行了reject 或nack 并将 requee 参数设置为 false )的时候,这个消息就会变成死信。
  • 消息本身设置了过期时间(TTL), 并且消息过期时间已经生效, 还未被消费的消息就会变成死信【特点是每个消息的过期时间都不同】
  • 可以设置队列中所有消息的过期时间,如果消息过期时间已经生效,消息还未被消费
  • 队列设置了最大长度限制, 当队列已满, 之后从交换机路由到该队列的消息会自动变成死信。

2、什么是死信交换机

死信交换机是专门处理死信的交换机

3、什么是死信队列

跟死信交换机绑定的队列就是死信队列,死信队列中存储的消息都是死信消息。

4、死信队列的应用

  • 保证消息不会丢失,保证数据的完整性;
  • 可以借助延时消费的特性完成特定的功能(比如订单生成但是未支付,超过30分钟自动取消的业务场景)

5、原理图介绍

6、三种场景代码演示

6.1 消费者拒绝消费消息, 消息进入死信队列

首先需要在application.yml文件中开启手动ack

spring:rabbitmq:# 开启消费者手动acklistener:direct:acknowledge-mode: manual

创建配置类
往容器中注入普通交换机、普通队列、路由规则和死信交换机和死信队列、死信路由规则

package com.kkarma.config;import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class DeadLettingConfig {public static final String GENERIC_EXCHANGE = "generic-exchange";public static final String GENERIC_QUEUE = "generic-queue";public static final String GENERIC_ROUTING_KEY = "generic.#";public static final String DEAD_EXCHANGE = "dead-exchange";public static final String DEAD_QUEUE = "dead-queue";public static final String DEAD_ROUTING_KEY = "dead.#";@Beanpublic Exchange genericExchange(){return ExchangeBuilder.topicExchange(GENERIC_EXCHANGE).build();}@Beanpublic Queue genericQueue(){return QueueBuilder.durable(GENERIC_QUEUE).deadLetterExchange(DEAD_EXCHANGE).deadLetterRoutingKey("dead.demo").build();}@Beanpublic Binding genericBinding(Queue genericQueue, Exchange genericExchange){return BindingBuilder.bind(genericQueue).to(genericExchange).with(GENERIC_ROUTING_KEY).noargs();}@Beanpublic Exchange deadExchange(){return ExchangeBuilder.topicExchange(DEAD_EXCHANGE).build();}@Beanpublic Queue deadQueue(){return QueueBuilder.durable(DEAD_QUEUE).build();}@Beanpublic Binding deadBinding(Queue deadQueue, Exchange deadExchange){return BindingBuilder.bind(deadQueue).to(deadExchange).with(DEAD_ROUTING_KEY).noargs();}
}

生产者端

package com.kkarma.deadletter;import com.kkarma.config.DeadLettingConfig;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.io.IOException;@SpringBootTest
public class Publisher {private final RabbitTemplate rabbitTemplate;@Autowiredpublic Publisher(RabbitTemplate rabbitTemplate){this.rabbitTemplate =  rabbitTemplate;}/*** 消费者拒绝消费,消息进入死信队列*/@Testpublic void push() throws IOException {rabbitTemplate.convertAndSend(DeadLettingConfig.GENERIC_EXCHANGE, "generic.demo", "正常消息被拒绝消息会变成死信...");System.out.println("消息发送成功...");System.in.read();}}

消费者端

package com.kkarma.deadletter;import com.kkarma.config.DeadLettingConfig;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;@Component
public class Consumer {@RabbitListener(queues = DeadLettingConfig.GENERIC_QUEUE)public void pullAndNack(String msg, Channel channel, Message message) throws Exception {System.out.println("接收generic-queue队列中的消息内容: " + msg);String correlationId = message.getMessageProperties().getCorrelationId();System.out.println("唯一标识: " + correlationId);// 拒绝消费消息channel.basicReject(message.getMessageProperties().getDeliveryTag(),false);// 确认未成功消费// channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);}
}

测试结果

6.2 消息指定过期时间

主要是生产者端在发送消息是指定消息的过期时间

    /*** 消息指定过期时间*/@Testpublic void publishMsgExpire(){String msg = "generic letter expire become dear letter";rabbitTemplate.convertAndSend(DeadLettingConfig.GENERIC_EXCHANGE, "generic.demo", msg, new MessagePostProcessor() {@Overridepublic Message postProcessMessage(Message message) throws AmqpException {message.getMessageProperties().setExpiration("10000");return message;}});}

6.3 给队列设置消息过期时间

这一项设置主要是通过DeadLettingConfig配置类中的正常队列来进行设置

    @Beanpublic Queue genericQueue(){// 这里需要指定当消息变成死信时绑定的死信交换机,并且需要重新指定指定死信交换机和死信队列之间的路由return QueueBuilder.durable(GENERIC_QUEUE).deadLetterExchange(DEAD_EXCHANGE).deadLetterRoutingKey("dead.demo")// 设置队列中消息的过期时间.ttl(10000).build();}

6.4 设置队列的最大长度

    @Beanpublic Queue genericQueue(){// 这里需要指定当消息变成死信时绑定的死信交换机,并且需要重新指定指定死信交换机和死信队列之间的路由return QueueBuilder.durable(GENERIC_QUEUE).deadLetterExchange(DEAD_EXCHANGE).deadLetterRoutingKey("dead.demo")// 设置队列最大长度,当队列已满,再路由过来的消息就被当成死信处理.maxlength(10).build();}

RabbitMQ中的死信及死信队列详解相关推荐

  1. MQ消息队列详解、四大MQ的优缺点分析

    MQ消息队列详解.四大MQ的优缺点分析 前言 面试题切入 面试官心理分析 面试题剖析 ①为什么要使用MQ 系统解耦 异步调用 流量削峰 消息队列的优缺点 四大主流MQ(kafka.ActiveMQ.R ...

  2. linux如何查看kafka消息队列,kafka以及消息队列详解

    kafka以及消息队列详解 Kafka 是LinkedIn 开发的一个高性能.分布式的消息系统. 用途:广泛用于日志收集.流式数据处理.在线和离线消息分发等场景. 1. Kafka 将消息流按Topi ...

  3. 教程-Delphi中Spcomm使用属性及用法详解

    Delphi中Spcomm使用属性及用法详解 Delphi是一种具有 功能强大.简便易用和代码执行速度快等优点的可视化快速应用开发工具,它在构架企业信息系统方面发挥着越来越重要的作用,许多程序员愿意选 ...

  4. JavaScript数据结构与算法——队列详解(下)

    接下来会借助本人另一篇文章JavaScript数据结构与算法--队列详解(上)中实现的队列类及其方法实现一个应用. 配对问题 需求分析:在一个文件中保存着一份男女混合的数据,名称前以B开头表示男士,以 ...

  5. 转:Java 7 种阻塞队列详解

    转自: Java 7 种阻塞队列详解 - 云+社区 - 腾讯云队列(Queue)是一种经常使用的集合.Queue 实际上是实现了一个先进先出(FIFO:First In First Out)的有序表. ...

  6. (08)System Verilog 队列详解

    (08)System Verilog 队列详解 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog 队列详解 5)结语 1.2 FPGA简 ...

  7. php读音量大小,Android_Android中实时获取音量分贝值详解,基础知识 度量声音强度,大 - phpStudy...

    Android中实时获取音量分贝值详解 基础知识 度量声音强度,大家最熟悉的单位就是分贝(decibel,缩写为dB).这是一个无纲量的相对单位,计算公式如下: 分子是测量值的声压,分母是参考值的声压 ...

  8. linux fq队列,QOS各种队列详解(FIFO,FQ,CBWFQ,PQ).doc

    QOS各种队列详解(FIFO,FQ,CBWFQ,PQ) QOS各种队列详解(FIFO,FQ,CBWFQ,PQ) 对于拥塞管理,一般采用队列技术,使用一个队列算法对流量进行分类,之后用某种优先级别算法将 ...

  9. python argv 详解_对python中的argv和argc使用详解

    主要问题 为什么argv中第一个,即index=0的内容就是文件名? python中argc是用什么实现的? 概念解释 argc:argument counter,命令行参数个数 argv:argum ...

  10. yii mysql 事务处理_Yii2中事务的使用实例代码详解

    前言 一般我们做业务逻辑,都不会仅仅关联一个数据表,所以,会面临事务问题. 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全 ...

最新文章

  1. .NET设计模式(2):单件模式(Singleton Pattern)
  2. pytorch 多进程队列
  3. MATLAB使用Python数值和字符变量
  4. 转化与流量到底哪一个更重要?
  5. 从思维导图学习操作系统(二)
  6. 复练-软考网规-IDS和IPS概念、分类、评价标准
  7. 学习笔记-error LNK2019
  8. linux构建基于mac的vlan,通过CLI配置交换机的基于MAC的VLAN组
  9. 数据饕餮,盛夏旋风!天善学院SVIP冰点促最后一波!
  10. 2015.10.7第一篇
  11. Uva 1588.Kickdown
  12. Win10打开或关闭任务栏系统图标
  13. Exploratory Data Analysis可视化分析美国天气
  14. 跨平台的会员通 打通品牌任督二脉
  15. Titan图形数据库的应用实例讲解
  16. C#模仿腾讯QQ源码下载(附效果图)_张童瑶的博客
  17. 51NOD 1631 小鲨鱼在51nod小学 区间线段树
  18. 17、前端开发:HTML知识补充——表格标签
  19. 关于人工智能与人脑思维的辩证思考
  20. FORBS企业500强

热门文章

  1. [js]windows下通过命令行运行javascript脚本,支持命令行参数
  2. Simulink仿真代码之step()函数的使用
  3. linux查看磁带机端口,Linux下使用磁带机的常用命令 tar
  4. 自定义指令与自定义指令的回调函数inserted和componentUpdated
  5. vue入门教程(一)
  6. 赵雅智_service电话监听2加接通电话录音
  7. AVProVideo视频插件使用
  8. Exclusive-OR hdu3234
  9. 车辆信息管理的简单实现
  10. 2021年中国便携式乳腺摄影平板探测器市场趋势报告、技术动态创新及2027年市场预测