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文件下创建一个接口 我创建…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...

【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...

ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...