RabbitMQ之延迟消息

文章目录

  • 前言
  • 一、死信交换机
  • 二、延迟消息
    • 死信交换机实现延迟消息
      • 图解流程
    • DelayExchange插件实现延迟消息
      • 安装插件
      • 声明延迟交换机
      • 发送延迟消息
  • 总结


前言

死信交换机、延迟消息


一、死信交换机

  • 当一个队列中的消息满足下列情况之一时,可以成为死信(dead letter):

    • 消费者使用basic.rejectbasic.nack声明消费失败,并且消息的requeue参数设置为false
    • 消息是一个过期消息,超时无人消费
    • 要投递的队列消息满了,无法投递
  • 如果一个队列中的消息已经成为死信,并且这个队列通过dead-letter-exchange属性指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而这个交换机就称为死信交换机(Dead Letter Exchange)。而此时加入有队列与死信交换机绑定,则最终死信就会被投递到这个队列中。

  • 死信交换机有什么作用呢?

    • 收集那些因处理失败而被拒绝的消息
    • 收集那些因队列满了而被拒绝的消息
    • 收集因TTL(有效期)到期的消息

二、延迟消息

上面讲诉的两种作用可以用来实现消费者重试的处理,即将处理失败、溢出的消息放在特定队列由人工处理,与消费者重试时讲的RepublishMessageRecoverer作用类似(在RabbitMQ之消费者的可靠性里讲过RepublishMessageRecoverer):

  • 收集那些因处理失败而被拒绝的消息
  • 收集那些因队列满了而被拒绝的消息

收集因TTL(有效期)到期的消息这个作用可以用来实现延迟消息

死信交换机实现延迟消息

  • 声明一个Fanout交换机ttl.fanout、一个队列ttl.queue、一个Direct交换机dragon.direct、一个队列directt.queue。发送的消息设置有效期RoutingKey是blue。
  • ttl.queue通过dead-letter-exchange属性绑定dragon.direct交换机,使dragon.direct成为死信交换机,这样ttl.queue队列中过期的消息成为死信就会自动到达dragon.direct中。
  • direct.queue队列通过RoutingKey与死信交换机dragon.direct绑定,且RoutingKey为blue,这样,过期的消息先到达死信交换机,因死信交换机与direct.queue通过RoutingKey绑定,过期的消息通过RoutingKey由死信交换机路由到direct.queue队列。
  • 此时若有消费者消费direct.queue队列,就实现了延迟消费,具体的延时时间就是设置的有效期时间。

图解流程

在这里插入图片描述

注意:

  • RabbitMQ的消息过期是基于追溯方式来实现的,也就是说当一个消息的TTL到期以后不一定会被移除或投递到死信交换机,而是在消息恰好处于队首时才会被处理。
  • 当队列中消息堆积很多的时候,过期消息可能不会被按时处理,因此你设置的TTL时间不一定准确。

DelayExchange插件实现延迟消息

安装插件

插件下载地址

在这里插入图片描述

将下载的文件放到了/mnt目录下,然后输入sudo docker ps命令查看自己的rabbitmq是否正在运行,如果不在运行则输入sudo docker start id这里填你自己的容器id,如果不知道自己id的,输入sudo docker pa -a查看。

在这里插入图片描述

当容器运行起来后,输入sudo docker cp /mnt/rabbitmq_delayed_message_exchange-3.12.0.ez rabbit:/plugins命令,将刚插件拷贝到容器内plugins目录下。

在这里插入图片描述

拷贝完成后,输入sudo docker exec -it rabbit /bin/bash命令,进入容器。
进入plugins文件夹

在这里插入图片描述

在容器内plugins目录下,查看插件是否上传成功ls -l|grep delay

在这里插入图片描述

然后启动插件,在当前目录下输入rabbitmq-plugins enable rabbitmq_delayed_message_exchange命令

在这里插入图片描述

到这里插件安装就完成了,接下来我们需要重启RabbitMQ容器。执行exit命令退出RabbitMQ容器内部,然后执行docker restart 容器名命令重启RabbitMQ容器

声明延迟交换机

两种方式,自行选择
基于注解:

@RabbitListener(bindings = @QueueBinding(
        value = @Queue(name = "delay.queue", durable = "true"),
        exchange = @Exchange(name = "delay.direct", delayed = "true"),
        key = "delay"
))
public void listenDelayMessage(String msg){
    log.info("接收到delay.queue的延迟消息:{}", msg);
}

基于bean:

package com.itheima.consumer.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Slf4j
@Configuration
public class DelayExchangeConfig {

    @Bean
    public DirectExchange delayExchange(){
        return ExchangeBuilder
                .directExchange("delay.direct") // 指定交换机类型和名称
                .delayed() // 设置delay的属性为true
                .durable(true) // 持久化
                .build();
    }

    @Bean
    public Queue delayedQueue(){
        return new Queue("delay.queue");
    }
    
    @Bean
    public Binding delayQueueBinding(){
        return BindingBuilder.bind(delayedQueue()).to(delayExchange()).with("delay");
    }
}

发送延迟消息

@Test
void testPublisherDelayMessage() {
    // 1.创建消息
    String message = "hello, delayed message";
    // 2.发送消息,利用消息后置处理器添加消息头
    rabbitTemplate.convertAndSend("delay.direct", "delay", message, new MessagePostProcessor() {
        @Override
        public Message postProcessMessage(Message message) throws AmqpException {
            // 添加延迟消息属性
            message.getMessageProperties().setDelay(5000);
            return message;
        }
    });
}

注意:
延迟消息插件内部会维护一个本地数据库表,同时使用Elang Timers功能实现计时。如果消息的延迟时间设置较长,可能会导致堆积的延迟消息非常多,会带来较大的CPU开销,同时延迟消息的时间会存在误差。因此,不建议设置延迟时间过长的延迟消息。


总结

以上就是延迟消息的详细讲解了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/196365.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot实现私人健身与教练预约管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现私人健身与教练预约管理系统演示 摘要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应…

编程学习及常见的技术难题

文章目录 编程学习及常见的技术难题引言如何学习编程学习参考开发工具推荐编程中常见的技术难题 编程学习及常见的技术难题 引言 学习编程是一件有趣也有挑战的事情,它可以让你创造出各种有用的软件,解决各种复杂的问题,甚至改变世界。 编程中…

VS2010配置opencv2.4.10

1.下载opencv2.4.10,百度网盘链接如下: 链接:https://pan.baidu.com/s/1UdoQJbRUEB_G2urT703xYQ 提取码:7lbd 2.运行opencv-2.4.10.exe,将文件提取到一个自定义目录里: 3.添加系统环境变量 在“系统变量…

序列化基础

1、简介 对象序列化的目标是将对象保存到磁盘中,或允许在网络中直接传输对象。它允许把内存中的 Java 对象转换成平台无关的二进制流(序列化,也称编码),并持久地保存在磁盘上或通过网络把这种二进制流传输到另一个网络…

Spring --- 创建一个Spring项目

文章目录 创建一个Maven项目添加Spring框架支持添加启动类 创建一个Maven项目 注:我们需要使用 Maven 来管理依赖,所以需要创建一个Maven项目 添加Spring框架支持 注: 添加这两个依赖才能正确使用 Spring在添加依赖后记得刷新,把依…

Vue3-Pinia

Pinia是什么 Pinia是Vue的最新状态管理工具,是Vuex的替代品 比Vuex更大的优势在于: 1.提供更加简单的API(去掉了mutation) 2.提供符合,组合式风格的API(和Vue3新语法统一) 3.去掉了modules…

JOSEF 漏电继电器JHOK-ZBL1 DH-50L 系统1140V 电源AC220V

系列型号: JHOK-ZBL多档切换式漏电(剩余)继电器 JHOK-ZBL1多档切换式漏电(剩余)继电器 JHOK-ZBL2多档切换式漏电(剩余)继电器 JHOK-ZBM多档切换式漏电(剩余)继电器 …

为品质加冕 | 喜尔康智家再次斩获大奖

近日,被誉为“家居质量界奥斯卡”的2023年度沸腾质量奖颁奖盛典在福建厦门第三届家居质量大会同期隆重举行。现场重磅揭晓2023年沸腾质量奖测评获奖结果。 今年,喜尔康智能家居再接再厉,从数百家参评企业中脱颖而出,参评的智能坐便…

解锁领先的有限元分析软件ABAQUS:不同版本功能特点及价格

随着科学技术的飞速发展,工程领域对于高效可靠的仿真软件需求日益增长。ABAQUS作为有限元分析领域的佼佼者,为工程师提供了强大而灵活的工具,用于模拟和分析复杂的结构和材料行为。本文将深入介绍ABAQUS的概念、不同版本的特点、功能区别、定…

Baby-Step Giant-Step Homomorphic DFT

参考文献: [CT65] Cooley J W, Tukey J W. An algorithm for the machine calculation of complex Fourier series[J]. Mathematics of computation, 1965, 19(90): 297-301.[Shoup95] Shoup V. A new polynomial factorization algorithm and its implementation[…

LeetCode Hot100 84.柱状图中最大的矩形

题目: 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 方法: 代码: class Solution {public int largestRectang…

WIFI HaLow技术引领智能互联,打破通信限制

在过去十年里,WIFI技术已在家庭和企业中建立起了庞大的网络,连接了数十亿智能互联设备,促进了信息的迅速传递。然而,当前的WIFI标准存在一些挑战,包括协议范围的限制和整体功能的受限,导致在较远距离进行通…

工艺系统所管理数字化实践

摘要 本文介绍了上海核工程设计研究院在数字化转型方面的实践,包括业务数字化和管理数字化两个方面。业务数字化方面,该院通过开发小工具改进工作流程。管理数字化方面,该院采用零代码平台集中管理管道力学信息相关模型和数据,并…

写了个数据查询为空的 Bug,你会怎么办?

大家在开发时,遇到的一个典型的 Bug 就是:为什么数据查询为空? 对应的现象就是:前端展示不出数据、或者后端查询到的数据列表为空。 遇到此类问题,其实是有经典的解决套路的,下面鱼皮给大家分享如何高效解决…

Python基础语法之学习print()函数

Python基础语法之学习print函数 1、代码2、效果 1、代码 print("Hello World") print("Hello World1","Hello World2") print("Hello World1\n","Hello World2") print("Hello World",end" 默认结束符是行号…

2.ORB-SLAM3中如何从二进制文件中加载多地图、关键帧、地图点等数据结构

目录 1 为什么保存&加载(视觉)地图 1.1 加载多地图的主函数 1.2 加载各个地图 Atlas::PostLoad 1.3 加载关键帧及地图点Map::PostLoad 1.4 恢复地图点信息 MapPoint::PostLoad 1.5 恢复关键帧信息KeyFrame::PostLoad 1 为什么保存&加载(视觉)地图 因为我们要去做导…

如何写好产品软文?软文撰写指南!

针对某种产品写一篇软文,我们应该怎么构思,怎么提笔去写,怎么写得让用户认可我们的产品,并产生消费的冲动,这是需要讲究技巧的。 今天伯乐网络传媒来给大家分享三个步骤,教你轻轻松松撰写一篇爆文&#xf…

记一次域控迁移并升级

域环境: 域控级别:windows server2008R2 主域控:win server 2008R2 辅域控:win server 2016 需求:新购一台win server 2022,需要将主域控迁移到新服务器中,并升级域控级别为最新 检查域控 …

什么软件能去水印?分享三款实用去水印工具

什么软件能去水印?去水印你还在担心会损伤画质或处理不干净?今天分享三款好用的图片去水印工具,手机和电脑软件都有,操作简单,去水印速度快,而且去水印后几乎看不水印痕迹! 1、水印云 一款图片编…

贪心算法策略实现

贪心算法 贪心算法:基于某种情况进行一个排序。 贪心算法得到的是优良解,而非全局最优解。需要证明局部最优解 全局最优解 经典贪心算法 —— 会议问题 对于这个问题 ,我们提出贪心策略: 策略1:按照会议的持续时间长…