RabbitMQ中的死信及死信队列详解
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中的死信及死信队列详解相关推荐
- MQ消息队列详解、四大MQ的优缺点分析
MQ消息队列详解.四大MQ的优缺点分析 前言 面试题切入 面试官心理分析 面试题剖析 ①为什么要使用MQ 系统解耦 异步调用 流量削峰 消息队列的优缺点 四大主流MQ(kafka.ActiveMQ.R ...
- linux如何查看kafka消息队列,kafka以及消息队列详解
kafka以及消息队列详解 Kafka 是LinkedIn 开发的一个高性能.分布式的消息系统. 用途:广泛用于日志收集.流式数据处理.在线和离线消息分发等场景. 1. Kafka 将消息流按Topi ...
- 教程-Delphi中Spcomm使用属性及用法详解
Delphi中Spcomm使用属性及用法详解 Delphi是一种具有 功能强大.简便易用和代码执行速度快等优点的可视化快速应用开发工具,它在构架企业信息系统方面发挥着越来越重要的作用,许多程序员愿意选 ...
- JavaScript数据结构与算法——队列详解(下)
接下来会借助本人另一篇文章JavaScript数据结构与算法--队列详解(上)中实现的队列类及其方法实现一个应用. 配对问题 需求分析:在一个文件中保存着一份男女混合的数据,名称前以B开头表示男士,以 ...
- 转:Java 7 种阻塞队列详解
转自: Java 7 种阻塞队列详解 - 云+社区 - 腾讯云队列(Queue)是一种经常使用的集合.Queue 实际上是实现了一个先进先出(FIFO:First In First Out)的有序表. ...
- (08)System Verilog 队列详解
(08)System Verilog 队列详解 1.1 目录 1)目录 2)FPGA简介 3)System Verilog简介 4)System Verilog 队列详解 5)结语 1.2 FPGA简 ...
- php读音量大小,Android_Android中实时获取音量分贝值详解,基础知识
度量声音强度,大 - phpStudy...
Android中实时获取音量分贝值详解 基础知识 度量声音强度,大家最熟悉的单位就是分贝(decibel,缩写为dB).这是一个无纲量的相对单位,计算公式如下: 分子是测量值的声压,分母是参考值的声压 ...
- linux fq队列,QOS各种队列详解(FIFO,FQ,CBWFQ,PQ).doc
QOS各种队列详解(FIFO,FQ,CBWFQ,PQ) QOS各种队列详解(FIFO,FQ,CBWFQ,PQ) 对于拥塞管理,一般采用队列技术,使用一个队列算法对流量进行分类,之后用某种优先级别算法将 ...
- python argv 详解_对python中的argv和argc使用详解
主要问题 为什么argv中第一个,即index=0的内容就是文件名? python中argc是用什么实现的? 概念解释 argc:argument counter,命令行参数个数 argv:argum ...
- yii mysql 事务处理_Yii2中事务的使用实例代码详解
前言 一般我们做业务逻辑,都不会仅仅关联一个数据表,所以,会面临事务问题. 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全 ...
最新文章
- .NET设计模式(2):单件模式(Singleton Pattern)
- pytorch 多进程队列
- MATLAB使用Python数值和字符变量
- 转化与流量到底哪一个更重要?
- 从思维导图学习操作系统(二)
- 复练-软考网规-IDS和IPS概念、分类、评价标准
- 学习笔记-error LNK2019
- linux构建基于mac的vlan,通过CLI配置交换机的基于MAC的VLAN组
- 数据饕餮,盛夏旋风!天善学院SVIP冰点促最后一波!
- 2015.10.7第一篇
- Uva 1588.Kickdown
- Win10打开或关闭任务栏系统图标
- Exploratory Data Analysis可视化分析美国天气
- 跨平台的会员通 打通品牌任督二脉
- Titan图形数据库的应用实例讲解
- C#模仿腾讯QQ源码下载(附效果图)_张童瑶的博客
- 51NOD 1631 小鲨鱼在51nod小学 区间线段树
- 17、前端开发:HTML知识补充——表格标签
- 关于人工智能与人脑思维的辩证思考
- FORBS企业500强