RabbitMQ常见问题之延迟消息

news2024/11/28 23:12:56

文章目录

  • 一、死信交换机
  • 二、TTL
      • 1. Queue指定死信交换机并设置TTL
      • 2. 消息设置TTL
  • 三、延迟队列
      • 1. SpringAMQP创建延迟队列
      • 2. 设置消息延迟
      • 3. 测试

一、死信交换机

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

  • 消费者使用basic.rejectbasic.nack声明消费失败,并且消息的requeue参数设置为false
  • 消息是一个过期消息,超时无人消费
  • 要投递的队列消息堆积满了,最早的消息可能成为死信

如果该队列配置了dead-letter-exchange属性,指定了一个交换机,那么队列中的死信就会投递到这个交换机中,而
这个交换机称为死信交换机(Dead Letter Exchange,简称DLX)。
在这里插入图片描述

二、TTL

在这里插入图片描述

如果messagequeue都有ttl,采用更小的一方。

1. Queue指定死信交换机并设置TTL

@Configuration
public class CommonConfig {
    @Bean
    public DirectExchange ttlExchange(){
        return new DirectExchange("ttl.direct");
    }

    @Bean
    public Queue ttlQueue(){
        return QueueBuilder
                .durable("ttl.queue")
                .ttl(10000)
                .deadLetterExchange("dl.direct")
                .deadLetterRoutingKey("dl")
                .build();
    }

    @Bean
    public Binding ttlBinding(){
        return BindingBuilder.bind(ttlQueue()).to(ttlExchange()).with("ttl");
    }
}

2. 消息设置TTL

@Test
public void testTTLMessage(){
    Message message = MessageBuilder.withBody("hello ttl".getBytes(StandardCharsets.UTF_8))
            .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
            .setExpiration("5000")
            .build();
    rabbitTemplate.convertAndSend("ttl.direct", "ttl", message);
    log.info("ttl消息已发送");
}

借助TTL机制可以用死信交换机模拟延迟队列,但是设计上比较牵强,性能不好。

三、延迟队列

这是官方提供的一些额外插件
https://www.rabbitmq.com/community-plugins.html

下载其中的DelayExchange插件,把.ez文件挂载到RabbitMQ容器的/plugins目录下,然后进入容器,执行

rabbitmq-plugins enable rabbitmq_delayed_message_exchange
root@7c4ba266e5bc:/# rabbitmq-plugins enable rabbitmq_delayed_message_exchange
Enabling plugins on node rabbit@7c4ba266e5bc:
rabbitmq_delayed_message_exchange
The following plugins have been configured:
  rabbitmq_delayed_message_exchange
  rabbitmq_management
  rabbitmq_management_agent
  rabbitmq_prometheus
  rabbitmq_web_dispatch
Applying plugin configuration to rabbit@7c4ba266e5bc...
The following plugins have been enabled:
  rabbitmq_delayed_message_exchange

started 1 plugins.

1. SpringAMQP创建延迟队列

基于@RabbitListener或者基于@Bean都可以。

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

在这里插入图片描述

2. 设置消息延迟

这个插件只能在消息上设置延迟时间,没有队列设置延迟时间的概念,不过都是一样的。
message要在Header上添加一个x-delay

    @Test
    public void testDelayMessage(){
        Message message = MessageBuilder.withBody("hello delay".getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                .setHeader("x-delay", 5000)
                .build();
        // confirm callback
        CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString());
        rabbitTemplate.convertAndSend("delay.direct", "delay", message, correlationData);
        log.info("发送消息成功");
    }

3. 测试

直接运行测试,可能会报错,因为rabbitmq意识到消息到了exchange却没有立即到queue,被认为错误,回调returnback,所以我们在ReturnCallBack中绕过这个限制。

@Slf4j
@Configuration
public class CommonConfig implements ApplicationContextAware {

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
        rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey)->{
            //check if is delay message
            if (message.getMessageProperties().getReceivedDelay() != null && message.getMessageProperties().getReceivedDelay() > 0) {
                return;
            }
            log.error("消息发送到queue失败,replyCode={}, reason={}, exchange={}, routeKey={}, message={}",
                    replyCode, replyText, exchange, routingKey, message.toString());
        });
    }
}

运行Test测试,可以看到Test方面,消息发送的时间为21:09:13

21:09:13:516  INFO 25468 --- [           main] o.s.a.r.c.CachingConnectionFactory       : Created new connection: rabbitConnectionFactory#2063c53e:0/SimpleConnection@6415f61e [delegate=amqp://rabbitmq@127.0.0.1:5672/, localPort= 62470]
21:09:13:557  INFO 25468 --- [           main] cn.itcast.mq.spring.SpringAmqpTest       : 发送消息成功

listener方面消息消费的时间为21:09:18,刚好5s。

21:08:31:952  INFO 19532 --- [           main] cn.itcast.mq.ConsumerApplication         : Started ConsumerApplication in 1.735 seconds (JVM running for 2.357)
21:09:18:583  INFO 19532 --- [ntContainer#0-1] c.i.mq.listener.SpringRabbitListener     : 消费者接收到delay.queue的延迟消息:【hello delay】

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

回馈科教,非凸科技助力第48届ICPC亚洲区决赛

1月12日-14日,“华为杯”第48届国际大学生程序设计竞赛(ICPC)亚洲区决赛在上海大学成功举办。非凸科技作为此次赛事的支持方之一,希望携手各方共同推动计算机科学和技术的发展。 这是一场智慧的巅峰对决,320支优秀队伍…

探索Java的神秘运行机制:揭秘整体运行流程

目录 1. 背景 2.整体流程 2.1 一看整体流程 2.1 再看运行流程 3. 类的加载过程 3.1 初探类的加载过程 4. 类加载机制 4.1 类加载器 4.2 双亲委派机制 5. 小结: 1. 背景 学习了这么多年的Java,把自己的理解写成JVM系列,以便于后面的…

openGauss学习笔记-200 openGauss 数据库运维-常见故障定位案例-表文件大小无变化

文章目录 openGauss学习笔记-200 openGauss 数据库运维-常见故障定位案例-表文件大小无变化200.1 VACUUM FULL一张表后,表文件大小无变化200.1.1 问题现象200.1.2 原因分析200.1.3 处理办法 openGauss学习笔记-200 openGauss 数据库运维-常见故障定位案例-表文件大小…

刷卡打印机,后台更换别人绑定的卡,无法生效,怎么解决?

环境: 柯美287打印机 问题描述: 刷卡打印机,后台更换别人绑定的卡,无法生效,怎么解决? 解决方案: 别人之前离职的卡刷了把他后面卡号复制好 2.搜索之前那个离职的用户,打开设置…

JavaScript 入门手册

准备好快速学习 JavaScript了吗? 如果是,那么你需要这份 JavaScript 小抄。它以清晰、简洁和初学者友好的方式介绍了 JavaScript 的基础知识。 将它作为提高 JavaScript 技能的参考或指南。 让我们深入学习。 什么是 JavaScript? JavaSc…

mPLUG-Owl2: 7B的多模态大模型

前言 语言模型:LLama2 - 7B视觉模型:Clip-L 0.3B 痛点 作者任务以往的方法(Qformer,linear层)直接将视觉编码器中的视觉特征映射到冻结的LLMs中,通过利用保留的语言能力执行多模态任务。这种策略限制了…

Springboot整合Canal 实践经验

文章目录 前言一、Canal 服务端:1.1 canal.properties:1.2 canal的监听实例: 二、canal客户端2.1 客户端配置要监听的实例:2.2 通过连接获取信息 总结 前言 本文是Springboot整合Canal 实践过程中经验记录; 一、Canal…

Linux/Networked

Enumeration nmap 网站更新之后有了一个引导模式,更利于学习了,之前看ippsec的视频,要不总是没有思路,现在出现的问题多了提示也更多了,还没有使用,一会用用再说 首先,第一个问题是“目标上正…

2 python快速上手

2 python快速上手 快速上手1.编码(密码本)2.编程初体验3.输出4. 初识数据类型4.1 整形(int)4.2 字符串(str)4.3 布尔类型(bool)4.4 类型转换 5. 变量5.1 变量名的规范5.2 变量内存指…

项目架构之Zabbix部署

1 项目架构 1.1 项目架构的组成 业务架构:客户端 → 防火墙 → 负载均衡(四层、七层) → web缓存/应用 → 业务逻辑(动态应用) → 数据缓存 → 数据持久层 运维架构:运维客户端 → 跳板机/堡垒机&#x…

探索Python数据结构与算法:解锁编程的无限可能

文章目录 一、引言1.1 数据结构与算法对于编程的重要性1.2 Python作为实现数据结构与算法的强大工具 二、列表和元组2.1 列表:创建列表、索引、切片和常用操作2.2 元组:不可变序列的特性和使用场景 三、字符串操作和正则表达式3.1 字符串的常见操作和方法…

本地运行LlaMA 2的简易指南

大家好,像LLaMA 2这样的新开源模型已经变得相当先进,并且可以免费使用。可以在商业上使用它们,也可以根据自己的数据进行微调,以开发专业版本。凭借其易用性,现在可以在自己的设备上本地运行它们。 本文将介绍如何下载…

0003.为什么有的电流表需要使用分流器?

以下两款电流表,你仔细看能有什么发现? 除了量程一个是20A,一个是30A,还有什么区别? 仔细观察你会发现30A的电流表上还有一个20A电流表没有的参数75mV. 是的,这就是他们之间最大的差距。 要测量一…

HTML--基本结构构成

基本结构&#xff1a; 文档声明: <!DOCTYPE html> htm标签对 :<html> </html> head标签对&#xff1a; <head> </head> body标签对&#xff1a;<body> </body> 如下结构&#xff1a; <html> <head> <title>这是一…

修改iview的表格table展开的默认icon和样式

修改前 修改后 修改内容 .title_label_list .ivu-icon-ios-add{font-size: 26px;color: #888888; } .title_label_list .ivu-icon-ios-add:hover{color: #11AAAA; } .title_label_list .ivu-icon-ios-add:before {content: "\F341"; } .title_label_list .ivu-icon-…

JVM工作原理与实战(十八):运行时数据区-堆

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、运行时数据区 二、堆 1.堆介绍 2.关键参数 总结 前言 ​JVM作为Java程序的运行环境&#xff0c;其负责解释和执行字节码&#xff0c;管理内存&#xff0c;确保安全&#xff0c…

Qt/QML编程之路:小键盘keyboard(36)

小键盘对于qml应用是经常用到的,在qml里面,就如一个fileDialog也要自己画一样,小键盘keyboard也是要自己画的,对于相应的每个按键的clicked都要一一实现的。 这里有一个示例: 代码如下: import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Window 2.0 im…

【刷题】 leetcode 2 .两数相加

两数相加 两数相加1 思路一 &#xff08;暴毙版&#xff09;2 思路二 &#xff08;本质出发&#xff09; 谢谢阅读Thanks♪(&#xff65;ω&#xff65;)&#xff89;下一篇文章见&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 两数相加 我们来看…

DQN、Double DQN、Dueling DQN、Per DQN、NoisyDQN 学习笔记

文章目录 DQN (Deep Q-Network)说明伪代码应用范围 Double DQN说明伪代码应用范围 Dueling DQN实现原理应用范围伪代码 Per DQN (Prioritized Experience Replay DQN)应用范围伪代码 NoisyDQN伪代码应用范围 部分内容与图片摘自&#xff1a;JoyRL 、 EasyRL DQN (Deep Q-Networ…

Queue详解(Java)

Queue详解 Java 中的队列&#xff08;Queue&#xff09;是一种数据结构&#xff0c;它遵循先进先出&#xff08;FIFO&#xff09;的原则。队列可以用于在一个集合中保存一组元素&#xff0c;并支持在队列的尾部添加元素&#xff0c;以及在队列的头部移除元素。 Java 标准库提…