Java消息队列:消息在什么时候会变成Dead Letter?

2023-05-16

在较为重要的业务队列中,确保未被正确消费的消息不被丢弃,通过配置死信队列,可以让未正确处理的消息暂存到另一个队列中,待后续排查清楚问题后,编写相应的处理代码来处理死信消息。

一、什么是死信队列

先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理解,一般来说,producer将消息投递到broker或者直接到queue里了,consumer从queue取出消息进行消费,但某些时候由于特定的原因导致queue中的某些消息无法被消费,这样的消息如果没有后续的处理,就变成了死信,有死信,自然就有了死信队列。

消息成为死信的三种情况:

1)队列消息数量到达限制;比如队列最大只能存储10条消息,而发了11条消息,根据先进先出,最先发的消息会进入死信队列;

2)消费者拒绝消费消息,并且不把消息重新放入原目标队列;

3)原队列存在消息过期设置,消息到达超时时间未被消费;

二、时间过期产生死信

生产者的主要配置 ,如下代码:

<!--

死信队列:

1. 声明正常的队列(test_queue_dlx)和交换机(test_exchange_dlx)

2. 声明死信队列(queue_dlx)和死信交换机(exchange_dlx)

3. 正常队列绑定死信交换机设置两个参数:

* x-dead-letter-exchange:死信交换机名称

* x-dead-letter-routing-key:发送给死信交换机的routingkey

-->

<!--

1. 声明正常的队列(test_queue_dlx)和交换机(test_exchange_dlx)

-->

<rabbit:queuename="test_queue_dlx"id="test_queue_dlx">

<!-- 正常队列绑定死信交换机-->

<rabbit:queue-arguments>

<!-- x-dead-letter-exchange:死信交换机名称-->

<entrykey="x-dead-letter-exchange"value="exchange_dlx"/>

<!-- x-dead-letter-routing-key:发送给死信交换机的routingkey-->

<entrykey="x-dead-letter-routing-key"value="dlx.hehe"></entry>

<!-- 设置队列的过期时间 ttl-->

<entrykey="x-message-ttl"value="10000"value-type="java.lang.Integer"/>

<!-- 设置队列的长度限制 max-length -->

<entrykey="x-max-length"value="10"value-type="java.lang.Integer"/>

</rabbit:queue-arguments>

</rabbit:queue>

<!--正常交换机-->

<rabbit:topic-exchangename="test_exchange_dlx">

<rabbit:bindings>

<rabbit:bindingpattern="test.dlx.#"queue="test_queue_dlx"></rabbit:binding>

</rabbit:bindings>

</rabbit:topic-exchange>

<!--

声明死信队列(queue_dlx)和死信交换机(exchange_dlx)

-->

<rabbit:queuename="queue_dlx"id="queue_dlx"></rabbit:queue>

<rabbit:topic-exchangename="exchange_dlx">

<rabbit:bindings>

<rabbit:bindingpattern="dlx.#"queue="queue_dlx"></rabbit:binding>

</rabbit:bindings>

</rabbit:topic-exchange>

在测试类中,添加如下方法,进行测试:

/**

* 发送测试死信消息:

* 1. 过期时间

*/

@Test

public void testDlx(){

//1. 测试过期时间,死信消息

rabbitTemplate.convertAndSend("test_exchange_dlx","test.dlx.haha","我是一条消息,我会变成死信消息吗?");

}

运行测试,查看管理台界面:

三、队列长度限制产生死信

修改测试类,添加测试方法:

/**

* 发送测试死信消息:

* 1. 过期时间

* 2. 长度限制

*/

@Test

public void testDlx(){

//1. 测试过期时间,死信消息

//rabbitTemplate.convertAndSend("test_exchange_dlx","test.dlx.haha","我是一条消息,我会变成死信消息吗?");

//2. 测试长度限制后,消息死信

for (int i = 0; i <11; i++) {

rabbitTemplate.convertAndSend("test_exchange_dlx","test.dlx.haha","我是一条消息,我会变成死信消息吗?");

}

}

运行测试方法进行测试:

四、消息拒收产生死信

在消费者工程创建 DlxListener:

import com.rabbitmq.client.Channel;

import org.springframework.amqp.core.Message;

import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;

import org.springframework.stereotype.Component;

@Component

public class DlxListener implements ChannelAwareMessageListener{

@Override

public void onMessage(Message message, Channel channel)throws Exception {

long deliveryTag = message.getMessageProperties().getDeliveryTag();

try {

//1.接收转换消息

System.out.println(new String(message.getBody()));

//2. 处理业务逻辑

System.out.println("处理业务逻辑...");

int i = 3/0;//出现错误

//3. 手动签收

channel.basicAck(deliveryTag,true);

} catch (Exception e) {

//e.printStackTrace();

System.out.println("出现异常,拒绝接受");

//4.拒绝签收,不重回队列 requeue=false

channel.basicNack(deliveryTag,true,false);

}

}

}

配置文件中消费者的配置:

<rabbit:listener-containerconnection-factory="connectionFactory"acknowledge="manual">

<!--定义监听器,监听正常队列-->

<rabbit:listenerref="dlxListener"queue-names="test_queue_dlx"></rabbit:listener>

</rabbit:listener-container>

生产者测试代码:

/** * 发送测试死信消息

* 1. 过期时间

* 2. 长度限制

* 3. 消息拒收

**/

@Test

public void testDlx(){

//1. 测试过期时间,死信消息

//rabbitTemplate.convertAndSend("test_exchange_dlx","test.dlx.haha","我是一条消息,我会变成死信消息吗?");

//2. 测试长度限制后,消息死信

// for (int i = 0; i < 20; i++) {

// rabbitTemplate.convertAndSend("test_exchange_dlx","test.dlx.haha","我是一条消息,我会变成死信消息吗?");

// }

//3. 测试消息拒收

rabbitTemplate.convertAndSend("test_exchange_dlx",

"test.dlx.haha",

"我是一条消息, 我会变成死信消息吗?");

}

发送消息,运行程序,查看后台管理界面:

五、死信的处理方式

死信的产生既然不可避免,那么就需要从实际的业务角度和场景出发,对这些死信进行后续的处理,常见的处理方式大致有下面几种:

1.丢弃,如果不是很重要,可以选择丢弃

2.记录死信入库,然后做后续的业务分析或处理

3.通过死信队列,由负责监听死信的应用程序进行处理

综合来看,更常用的做法是第三种,即通过死信队列,将产生的死信通过程序的配置路由到指定的死信队列,然后应用监听死信队列,对接收到的死信做后续的处理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java消息队列:消息在什么时候会变成Dead Letter? 的相关文章

随机推荐

  • ubuntu设置默认内核启动的方法

    本文介绍ubuntu设置默认内核启动的方法 参考如下图 xff0c 修改grub文件 xff1a 修改后 xff0c 执行 xff1a sudo update grub amp amp reboot
  • QML自定义的日历控件

    QML中提供了日历的控件Calendar xff0c 但该控件为QtQuick Controls 1中提供的控件 xff0c 因此只能使用QtQuick Controls Styles的方式对该控件进行设置 xff0c 效果如图 xff1a
  • QML地图Map中使用QPainterPath,并显示任意点经纬度位置

    QML地图Map中提供了供绘制图形的组件 xff0c 例如MapPolyline xff0c MapCircle等 xff0c 但是这些组件在绘制复杂轨迹时就显得功能不够全面 xff0c 因此我将QPainterPath在Map中进行使用并
  • QML地图绘制虚线

    QML提供了MapPolyline用于在地图上绘制线段 xff0c 该线段是实线 xff0c 因此我使用Canvas自定义绘制的方式在地图上绘制线段 xff0c 如图 xff1a 鼠标在地图上点击后 xff0c 在点击位置添加图标 xff0
  • QML无边框最大化窗口时遮住了任务栏,程序默认置顶的问题

    在QML窗口使用无边框 xff0c 并且默认程序最大化显示后 xff0c 此时程序显示默认自动变成了全屏显示 xff0c 程序自动遮挡住了系统任务栏 当使用多屏幕显示时 xff0c 切换不同程序 xff0c 该QML程序的界面显示错误 使用
  • 用VScode写C/C++,从下载安装到配置使用

    介绍 编程的过程大致分为编写代码 代码编译 代码执行三步 xff0c vscode可以完成代码编写 xff0c 但是不能进行编译 也就是将代码翻译为计算机可以听懂的话 xff0c MinGW可以完成这个任务 xff0c 二者配合可以实现在v
  • 深度学习训练降低显存指南

    一 小模块API参数inplace设置为True xff08 省一点点 xff09 比如 xff1a Relu 有一个默认参数inplace xff0c 默认设置为False xff0c 当设置为True时 xff0c 计算时的得到的新值不
  • C++工程师学习内容

    C 43 43 是最贴近底层编程语言 在性能方面上 xff0c 有着无可替代的优势特别是对于很多游戏开发公司来说 xff0c C 43 43 尤其适合作为后端服务的开发语言 在一些对于并发性能要求较高的业务上 xff0c C 43 43 也
  • Ubuntu 更新apt出错

    输入sudo apt get update后出现 Err 1 http us archive ubuntu com ubuntu xenial InRelease Temporary failure resolving 39 us arch
  • 使用OpenWrt开发嵌入式Linux(二):先让系统跑起来(使用initramfs)

    安装相关工具 推荐使用ubuntu 16及以上版本 sudo apt install gcc binutils bzip2 flex python perl make diffutils unzip gawk subversion zlib
  • 使用kubeadm从0到1搭建kubernete集群

    目录 概述 安装前提示 安装docker 安装kubeadm 安装kubernete集群master节点 安装 kubeadm kubectl kubelet组件 安装kubernete master节点 安装CNI网络插件 部署集群wor
  • shell基础之变量(2):变量有哪些种类、怎么定义/赋值/取值、不同种类变量的作用域

    通过本文能对shell变量有一个系统性的了解 xff0c 具体的包括 xff1a 变量的种类 xff1a 局部 全局 环境变量变量的定义和操作 xff1a 赋值 取值 取消变量变量的作用域 文章目录 一 变量的种类1 全局变量2 局部变量
  • java 泛型全解 - 绝对最详细

    背景 对于java的泛型我一直属于一知半解的 xff0c 平常真心用的不多 直到阅读 Effect Java 看到很多平常不了解的用法 xff0c 才下定决心 xff0c 需要系统的学习 xff0c 并且记录下来 1 泛型的概述 xff1a
  • Zookeeper数据同步流程

    在服务器启动阶段 xff0c 会进行磁盘数据的恢复 xff0c 完成数据恢复后就会进行Leader选举 一旦选举产生Leader服务器后 xff0c 就立即开始进行集群间的数据同步 xff0c 在整个过程中 xff0c Zookeeper都
  • JS中Ajax的方法和应用

    XMLHttpRequest对象 Ajax技术的核心是XMLHttpRequest对象 xff08 简称XHR xff09 这是有微软率先引入的一个特性 xff0c 其他浏览器提供商后来都提供了相同的实现 但因为IE的兼容性问题 xff0c
  • node.js安装及环境配置

    一 下载nodejs的安装包 xff1a 下载地址 xff1a https nodejs org zh cn download 根据自己电脑系统及位数选择 xff0c 一般都选择windows64位 msi格式安装包 网站上提供的安装包版本
  • 6个常用的React组件库

    Ant Design 项目链接 xff1a Ant Design 包大小 xff08 来自 BundlePhobia xff09 xff1a 缩小后 1 2mB xff0c 缩小 43 gzip 压缩后 349 2kB xff0c 通过摇树
  • 大数据培训课程数据清洗案例实操-简单解析版

    数据清洗 xff08 ETL xff09 在运行核心业务MapReduce程序之前 xff0c 往往要先对数据进行清洗 xff0c 清理掉不符合用户要求的数据 清理的过程往往只需要运行Mapper程序 xff0c 不需要运行Reduce程序
  • 宋红康2023版Java视频发布

    1500万 43 播放量见证经典 xff0c 尚硅谷宋红康老师的Java入门视频堪称神作 xff0c 如今经典再次超级进化 xff0c 新版Java视频教程震撼来袭 xff01 开发环境全新升级 xff1a JDK17 43 IDEA202
  • Java消息队列:消息在什么时候会变成Dead Letter?

    在较为重要的业务队列中 xff0c 确保未被正确消费的消息不被丢弃 xff0c 通过配置死信队列 xff0c 可以让未正确处理的消息暂存到另一个队列中 xff0c 待后续排查清楚问题后 xff0c 编写相应的处理代码来处理死信消息 一 什么