RabbitMQ - 死信、TTL原理、延迟队列安装和配置
目录
一、死信交换机
1.1、什么是死信交换机
1.2、TTL
1.2.1、什么是 TTL
1.2.2、通过 TTL 模拟触发死信
二、延迟队列
2.1、什么是延迟队列
2.2、配置延迟队列插件
2.2.1、延迟队列配置
a)下载镜像
b)运行容器
c)刚刚设定的RabbitMQ的数据卷名称为`mq-plugins`,所以我们使用下面命令查看数据卷:
d)在此目录下,进入 MQ 容器内部.
e)开启插件
2.3、SpringAMQP 使用延迟队列插件
一、死信交换机
1.1、什么是死信交换机
想要知道什么是死信交换机,先来看看什么是死信(dead letter)~
当生产者发送了一个消息,经过交换机到达队列时,满足下列情况之一时,就可以成为死信:
- 消费者使用 basic.reject 或 basic.nack 声明消费失败,并且消息的 requeue 参数设置为 false(消息不重新加入到队列中).
- 消息设置了过期时间,到了时间没有被消费掉.
- 要投递的队列消息堆积满了(队列设置了最大消息数目),最早的消息可能会成为死信(LRU 算法淘汰的消息).
那么如果这个时候,一个队列配置了 dead-letter-exchange 属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机就称为 死信交换机.
1.2、TTL
1.2.1、什么是 TTL
TTL 就是过期时间. 如果一个队列中的消息到了过期时间还没有被消费, 就会变成死信.
这里的消息到了过期时间实际上有两种情况:
- 消息所在的队列设置了消息过期时间(x_message_ttl).
- 消息本身设置了存活时间.
1.2.2、通过 TTL 模拟触发死信
a)声明一个直接交换机和一个配置了过期时间(x-message-ttl 属性)以及配 deadLetterExchange、deadLetterRoutingKey 属性的普通队列,用来生成死信
@Configuration
public class TTLMessageConfig {@Beanpublic DirectExchange ttlDirectExchange() {return new DirectExchange("ttl.direct");}@Beanpublic Queue ttlQueue() {return QueueBuilder.durable("ttl.queue").ttl(5000) //延时 5 s.deadLetterExchange("dl.direct") //消息如果超时没被消费就给这个死信交换机.deadLetterRoutingKey("dl").build();}@Beanpublic Binding ttlBinding() {return BindingBuilder.bind(ttlQueue()).to(ttlDirectExchange()).with("ttl");}}
b)这里我们基于注解的方式,声明一组死信交换机和队列
@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "dl.queue", durable = "true"),exchange = @Exchange(name = "dl.exchange"),key = "dl"))public void listenDlQueue(String msg) {log.info("消费者收到死信消息!msg=" + msg);}
c)生产者发送一个过期时间为 5s 的消息
@Testpublic void testTTLMessage() {//1.构造一个消息Message message = MessageBuilder.withBody("hello ttl message".getBytes()).setDeliveryMode(MessageDeliveryMode.PERSISTENT).setExpiration("5000").build();//2.发送消息rabbitTemplate.convertAndSend("ttl.direct", "ttl", message);//3.记录日志log.info("消息已经成功发送!");}
d)执行结果如下
Ps:通过执行结果,也可以看出,如果消息和队列都设置了过期时间,那么以时间短的为主.
二、延迟队列
2.1、什么是延迟队列
刚刚我们利用 TTL 结合死信交换机,实现了当消息发出后,消费者延迟收到消息的效果。这种消息模式就成为 延迟队列(Delay Queue) 模式。
延迟队列经常用于以下场景:
- 延迟发送短信.
- 用户下单,如果再 5 分钟内没有支付,就自动取消.
- 预约工作会议,10 分钟后自动通知所有参会人员.
2.2、配置延迟队列插件
由于 利用 TTL 结合死信交换机的方式实现起来比较麻烦,并且延迟队列的需求又非常多,因此 RabbitMQ 官方推出了一个插件,可以通过更简单的方式,达到延迟队列的效果.
2.2.1、延迟队列配置
我们在Centos7虚拟机中使用Docker来安装。
a)下载镜像
docker pull rabbitmq:3.8-management
b)运行容器
docker run \-e RABBITMQ_DEFAULT_USER=itcast \-e RABBITMQ_DEFAULT_PASS=123321 \-v mq-plugins:/plugins \--name mq \--hostname mq1 \-p 15672:15672 \-p 5672:5672 \-d \rabbitmq:3.8-management
Ps:此命令还额外配置了插件目录对应的数据卷.
c)刚刚设定的RabbitMQ的数据卷名称为`mq-plugins`,所以我们使用下面命令查看数据卷:
docker volume inspect mq-plugins
结果如下
使用 cd 命令切换到 Mountpoint 指定的目录下.
d)在此目录下,进入 MQ 容器内部.
我的容器名为`mq`,所以执行下面命令:
docker exec -it mq bash
e)开启插件
进入容器内部后,执行以下命令开启插件:
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
2.3、SpringAMQP 使用延迟队列插件
a)声明一个延迟队列. 这里实际上和声明普通交换机只多出了一个 delayed 属性,设置为 true 就表示为延迟队列.
以下是基于 注解的方式声明交换机、队列、绑定.
Ps:如果是通过 java 代码的方式声明交换机,只需要 ExchangeBuilder().directExhange.delay() 即可.
@Component
@Slf4j
public class SpringRabbitListener {@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "delay.queue", durable = "true"),exchange = @Exchange(name = "delay.direct", delayed = "true"),key = "delay"))public void listenDelayExchange(String msg) {log.info("消费者接收到到了延迟消息!msg=" + msg);}}
b)生产者只需要在生产消息的时候添加一个 header:"x-delay",对应的值就是延迟时间,单位是毫秒:
@Testpublic void testDelayMessage() {//1.准备消息Message message = MessageBuilder.withBody("hello ttl message".getBytes()).setDeliveryMode(MessageDeliveryMode.PERSISTENT).setHeader("x-delay", 5000) // 消息延迟时间.build();//2.消息 ID 需要封装到 CorrelationData 中CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());//3.发送消息rabbitTemplate.convertAndSend("delay.direct", "delay", message, correlationData);log.info("消息已经成功发送!");}
c)结果如下
相关文章:

RabbitMQ - 死信、TTL原理、延迟队列安装和配置
目录 一、死信交换机 1.1、什么是死信交换机 1.2、TTL 1.2.1、什么是 TTL 1.2.2、通过 TTL 模拟触发死信 二、延迟队列 2.1、什么是延迟队列 2.2、配置延迟队列插件 2.2.1、延迟队列配置 a)下载镜像 b)运行容器 c)刚刚设定的Rabb…...

大数据与云计算实验一
检查是否开启 sudo service docker status 开启服务 sudo service docker start 运行服务 sudo docker run -itd -p 8080:80 nginx 查询ID docker ps -all 进入容器shell sudo docker exec -it <容器ID或容器名称> /bin/bash 找到/usr/share/nginx/html/index.…...

实施主品牌进化战略(一):确立主品牌进化架构
主品牌进化战略,即以主品牌为核心创造、巩固、转化竞争优势应对竞争环境变化,避免衰退,回归增长,让主品牌进化的方法论体系。主品牌进化战略制定要从 4 个方面出发:确立主品牌进化架构、更新和明确主品牌竞争方向、建立…...

linux搭建单机ES,集成ik分词器,文本抽取,Kibana可视化平台
Elasticsearch单机(Linux) 准备工作 第一项: 创建运行Elasticsearch和Kibana专用的普通用户,因为 elasticsearch 和 kibana 不允许使用 root用户启动,所以需要创建新用户启动。 linux用root权限创建一个用户赋权即可…...

金融和大模型的“两层皮”问题
几年前,我采访一位产业专家,他提到了一个高科技到产业落地的主要困惑:两层皮。 一些特别牛的技术成果在论文上发表了,这是一层皮。企业的技术人员,将这些成果产品化、商品化的时候,可能出于工程化的原因&am…...

智能生活从这里开始:数字孪生驱动的社区
数字孪生技术,这个近年来备受瞩目的名词,正迅速渗透到社区发展领域,改变着我们居住的方式、管理的方式以及与周围环境互动的方式。它不仅仅是一种概念,更是一种变革,下面我们将探讨数字孪生技术如何推动社区智能化发展…...

Python计算机二级知识点整理
1.当一个进程在运行过程中释放了系统资源后要调用 唤醒进程原语 唤醒进程原语是把进程从等待队列里移出到就绪队列并设置进程为就绪状态,当一个进程在运行过程中释放了系统资源后进入就绪状态,调用唤醒进程原语。 2. 3. 4.在希尔排序法中&#x…...

双系统ubuntu20.04(neotic版本)从0实现Gazebo仿真slam建图
双系统ubuntu20.04(neotic版本)从0实现Gazebo仿真slam建图 昨晚完成了ROS的多机通讯,还没来得及整理相关操作步骤,在进行实际小车的实验之前,还是先打算在仿真环境中进行测试,熟悉相关的操作步骤,计划通过虚拟机&…...

(JavaEE)(多线程案例)线程池 (简单介绍了工厂模式)(含经典面试题ThreadPoolExector构造方法)
线程诞生的意义,是因为进程的创建/销毁,太重了(比较慢),虽然和进程比,线程更快了,但是如果进一步提高线程创建销毁的频率,线程的开销就不能忽视了。 这时候我们就要找一些其他的办法…...

单播与多播mac地址
MAC 地址(Media Access Control Address)是一个用于识别网络设备的唯一标识符。每个网络设备都有一个独特的 MAC 地址,用于在局域网中进行通信。 单播MAC地址:单播MAC地址用于单播通信,即一对一的通信模式。当设备发送…...

反向动力学Ik学习
参考文章:(非本人原创) 英文原文:Inverse Kinematics Techniques in Computer Graphics: A Survey (andreasaristidou.com) 知乎翻译文章: 【游戏开发】逆向运动学(IK)详解 - 知乎 (zhihu.co…...

基于Levenberg-Marquardt算法的声源定位matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 .................................................................... %ML if (bML1)varxs…...

vscode的Emmet语法失效
解决方案:设置 -> 搜索Emmet -> 勾选 Emmet:Trigger Expansion On Tab和Emmet: Use Inline Completions -> 重启 注:Emmet语法是vscode自带的语法,可以快速生成HTML结构/CSS样式/格式化语法 Emmet语法 参考:关于vscode使…...

堆排序(大根堆)
堆的定义如下,n个关键字序列[1...n]称为堆,当且仅当满足: a(i)>a(2i)且a(i)>a(2i1) 这个为大根堆 a(i)<a(2i)且a(i)<a(2i 1) 这个为小根堆 通过建堆得到大根堆 大根堆 87,45,78,32,17,65,53,9 可以看成 …...

Mybatis学习笔记3 在Web中应用Mybatis
Mybatis学习笔记2 增删改查及核心配置文件详解_biubiubiu0706的博客-CSDN博客 技术栈:HTMLServletMybatis 学习目标: 掌握mybatis在web应用中如何使用 Mybatis三大对对象的作用域和生命周期 关于Mybatis中三大对象的作用域和生命周期、 官网说明 ThreadLocal原理及使用 巩…...

软件测试之功能测试详解
一、功能测试概述 1)功能测试就是对产品的各功能进行验证,根据功能测试用例,逐项测试,检查产品是否达到用户要求的功能。 2)功能测试,根据产品特性、操作描述和用户方案,测试一个产品的特性和…...
javascript选取元素的范围,可以包含父级,也可以不包含父级
//函数可以选取元素的范围,对于要选取文本的非常方便,或选取特定的子节点 function getRange(element){//判断是否支持range范围选取var supdocument.implementation.hasFeature("Range","2.0");var also(typeof document.createRan…...

QGIS怎么修改源代码?持续更新...
修改配置文件保存位置 修改目的:放着和本地安装的其他QGIS共用一份配置文件 修改文件:core/qgsuserprofilemanager.cpp 修改位置:第37行 return basePath QDir::separator() "my_profiles";修改完毕后,再次生成一下…...

dev board sig技术文章:轻量系统适配ARM架构芯片平台
摘要:本文简单介绍OpenHarmony轻量系统移植,会分多篇 适合群体:想自己动手移植OpenHarmony轻量系统的朋友 开始尝试讲解一下系统的移植,主要是轻量系统,也可能会顺便讲下L1移植。 1.1移植类型 OpenHarmony轻量系统的…...

MyBatis之增删查改功能
文章目录 一、创建各种类二、MyBatis的各种功能 1、查询<select>2、增加<insert>3、修改<update>4、删除<delete>三、总结 前言 在MyBatis项目中编写代码实现对MySql数据库的增删查改 一、创建各种类 1、在Java包的mapper文件下创建一个接口 我创建…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式
简介 在我的 QT/C 开发工作中,合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式:工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...