第十四章 RabbitMQ延迟消息之延迟队列

目录

一、引言

二、死信队列

三、核心代码实现

四、运行效果 

五、总结


一、引言

什么是延迟消息?

发送者发送消息时指定一个时间,消费者不会立刻收到消息,而是在指定时间后收到消息。

什么是延迟任务?

设置在一定时间之后才执行的任务。

延迟消息使用场景

我们在实际项目中经常会有一些场景,需要延迟指定时间后发送消息,比如在电商或者外卖平台中订单10分钟后自动取消功能等。

对于上述延迟消息的场景,我们该怎么实现呢?

RabbitMQ 官方并没有直接内置延迟消息的功能,但是可以通过 TTL(Time-To-Live)和死信队列(Dead Letter Exchanges)的组合来实现延迟消息的效果,另外RabbitMQ 也可以通过安装延迟消息插件的方式来实现。

二、死信队列

电商购物中,针对用户下单扣减库存的服务逻辑,我们希望删除10分钟后状态为未支付的订单。在过去的项目中,我们可能第一时间会想到通过定时任务定期查询未支付的订单并做删除来实现:

定时任务会有两个问题:

1. 当针对订单量特别大的电商项目而言,定时任务间断性地查询整个订单数据会极大增加订单服务的压力。

2. 定时任务存在时间上的滞后性。

通过使用RabbitMQ延迟消息,我们可以在完成需求的同时,有效的避免上述问题。如下图所示,用户通过交易服务下单(状态为未支付),随后交易服务调用商品服务扣减库存。 用户在调用交易服务的同时发送一个延迟消息到RabbitMQ,10分钟后交易服务收到消息,此时如果订单还是未支付状态,则取消订单。

RabbitMQ中的死信队列,就是一种可以实现延迟消息的方式。当一个队列中的消息满足下列情况之一时,就会成为死信(dead letter):

1. 消费者使用basic.reject或 basic.nack声明消费失败,并且消息的requeue参数设置为false

2. 消息是一个过期消息(达到了队列或消息本身设置的过期时间),超时无人消费

3. 要投递的队列消息堆积满了,最早的消息可能成为死信

如果队列通过dead-letter-exchange属性指定了一个交换机,那么该队列中的死信就会投递到这个交换机中。这个交换机称为死信交换机(Dead Letter Exchange,简称DLX)。

三、核心代码实现

package com.example.consumer;import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 常规的RabbitMQ 交换机/队列绑定配置类*/
@Configuration
public class RabbitMQConfig {@BeanQueue normalQueue() {// 使用 QueueBuilder 创建一个持久化队列return QueueBuilder.durable("normal.queue").deadLetterExchange("dead.direct").deadLetterRoutingKey("dead").build();}@BeanDirectExchange normalDirect() {return ExchangeBuilder.directExchange("normal.direct").build();}@BeanBinding bindingNormal(Queue normalQueue, DirectExchange normalDirect) {return BindingBuilder.bind(normalQueue).to(normalDirect).with("normal");}@BeanQueue deadQueue() {// 使用 QueueBuilder 创建一个持久化队列return QueueBuilder.durable("dead.queue").build();}@BeanDirectExchange deadDirect() {return ExchangeBuilder.directExchange("dead.direct").build();}@BeanBinding bindingDead(Queue deadQueue, DirectExchange deadDirect) {return BindingBuilder.bind(deadQueue).to(deadDirect).with("dead");}
}
package com.example.publisher;import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.test.context.SpringBootTest;import java.nio.charset.StandardCharsets;/*** 生产者*/
@Slf4j
@SpringBootTest
class PublisherApplicationTests {@Resourceprivate RabbitTemplate rabbitTemplate;@Testvoid test() {String content = "生活不易,所以保持足够的努力,对自己要有信心,积极地去面对工作生活的挑战!";Message message = MessageBuilder.withBody(content.getBytes(StandardCharsets.UTF_8)).setExpiration("10000").build();rabbitTemplate.convertAndSend("normal.direct","normal", message);}
}
package com.example.consumer;import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;import java.nio.charset.StandardCharsets;/*** 消费者*/
@Slf4j
@Component
public class SimpleListener {@RabbitListener(queues = "dead.queue")public void listener1(Message message) throws Exception {String msg = new String(message.getBody(), StandardCharsets.UTF_8); ;System.out.println("消费者1:人生是个不断攀登的过程【" + msg + "】");}
}

四、运行效果 

五、总结

虽然我们通过RabbitMQ的死信队列能够实现延迟消息的功能,但是通过代码我们可以看到,这种实现方式相对来说比较繁琐。而且关键是RabbitMQ提供死信队列的初衷并不是让我们用来发送延迟消息的,而是为了作为兜底方案,来接收没有消费的死信的,便于定位问题。因此,后续章节会给大家讲解更优的解决方案,即延迟插件。

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

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

相关文章

深入探讨C++多线程性能优化

深入探讨C多线程性能优化 在现代软件开发中,多线程编程已成为提升应用程序性能和响应速度的关键技术之一。尤其在C领域,多线程编程不仅能充分利用多核处理器的优势,还能显著提高计算密集型任务的效率。然而,多线程编程也带来了诸…

大模型微调实战指南:从零开始手把手教你微调大模型

文末有福利! 今天分享一篇技术文章,你可能听说过很多大模型的知识,但却从未亲自使用或微调过大模型。 今天这篇文章,就手把手带你从零微调一个大模型。 大模型微调本身是一件非常复杂且技术难度很高的任务,因此本篇…

为什么在Anaconda中会报错‘chcp‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件?

首先,我们需要知道,这意味着chcp 命令在系统路径中找不到。chcp(Change Code Page)是一个Windows命令行工具,用于查看或设置活动控制台窗口的代码页。 经过统计整合了一些原因如下: 1.系统环境变量被错误地修改 可能导致系统命…

【closerAI ComfyUI】真人秒变卡通,相似度爆表!炫酷工作流,让你的卡通写真秒变朋友圈焦点!快来试试吧!

【closerAI ComfyUI】真人卡通化,超像!这个工作流真棒!用个人写真照片转卡通风格去轰炸你的朋友圈吧! 这期我们主要讨论如何使用stable diffusion comfyUI 制作定制写真卡通照片工作流。也就是真人照片转卡通形象。 closerAI工作…

什么是乐观锁、悲观锁?

什么是乐观锁、悲观锁? 乐观锁:乐观锁和悲观锁是并发控制的两种方式,用来确保在多线程或多用户访问共享资源时,数据的一致性和完整性。 悲观锁(Pessimistic Lock) 悲观锁假设并发操作会经常发生&#xf…

【漏洞复现】SpringBlade menu/list SQL注入漏洞

》》》产品描述《《《 致远互联智能协同是一个信息窗口与工作界面,进行所有信息的分类组合和聚合推送呈现。通过面向角色化、业务化、多终端的多维信息空间设计,为不同组织提供协同门户,打破组织内信息壁垒,构建统一协同沟通的平台。 》》》漏洞描述《《《 致远互联 FE协作办公…

【PyTorch】DataLoader 设置 num_workers > 0 时,出现 CUDA with multiprocessing 相关报错

【PyTorch】DataLoader 设置 num_workers > 0 时,出现 CUDA with multiprocessing 相关报错 1 报错信息2 报错分析2.1 原因2.2 结论 3 解决方法 1 报错信息 RuntimeError: Caught RuntimeError in DataLoader worker process 0.RuntimeError: Cannot re-initial…

mac安装homebrew和git

简介 由于把自己的新mac拿来撸代码,开始环境搭建,安装各种工具和依赖,安装 git 需要先安装 homebrew,然后就遇到了 homebrew 安装失败的问题。 curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection…

基于SpringBoot+Vue+uniapp的C语言在线评测系统的详细设计和实现

详细视频演示 请联系我获取更详细的演示视频 项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不…

NewStarCTF2024-Week2-Web-WP

目录 1、复读机 2、你能在一秒内打出八句英文吗 3、遗失的拉链 4、谢谢皮蛋 plus 5、PangBai 过家家(2) 1、复读机 测了下存在 ssti 没什么说的 fenjing 秒了 2、你能在一秒内打出八句英文吗 每次出来的需要提交的内容都不一样 exp: …

如何从头训练大语言模型: A simple technical report

写在前面 自8月底训好自己的1.5B的LLM后,一直都没有发布一个完整的技术报告,不少小伙伴私信我催更,千呼万唤始出来。其实也没有太大动力去做,原因有三: 豁然开朗:搞定全流程之后,对LLM确实豁然…

静止的秘密

在未来的某一天,科技已经发展到了令人难以置信的地步。在这个时代,视频不再是简单的记录工具,而是成为了连接现实与虚拟世界的桥梁。在这个背景下,一位名叫陈欣的年轻女程序员,发明了一种名为“时间镜像”的技术&#…

智能去毛刺:2D视觉引导机器人如何重塑制造业未来

机器人技术已经深入到各个工业领域中,为制造业带来了前所未有的变革。其中,2D视觉引导机器人技术以其精准、高效的特点,在去毛刺工艺中发挥着越来越重要的作用。本文将为您介绍2D视觉引导机器人技术的基本原理及其在去毛刺工艺中的应用&#…

Cortex-A7:一级页表(First level address translation)描述符格式及虚拟地址(VA)到物理地址(PA)转换过程

0 参考资料 ARM Cortex-A(armV7)编程手册V4.0.pdf1 Cortex-A7:一级页表(First level address translation)描述符格式及虚拟地址(VA)到物理地址(PA)转换过程 1.1 一级页表(First l…

白银票据、黄金票据和委派攻击(内网渗透)

今日你心思不在,心思不在则气息不在,气息不在则步伐不在,步伐不在,命安在。 文章目录 kerberos协议主要角色协议工作流程 白银票据白银票据伪造条件 黄金票据黄金票据伪造条件 白银票据和黄金票据哪个危害更大委派攻击非约束性委…

界面耻辱纪念堂--可视元素04

当我们第一次注意到 Visual Basic 5.0 菜单的动画效果“特性”时,我们只能嘲笑这种特性的傻气。事实上,我们并不觉得特性本身傻气,而是微软为这个特性投资,然后将这个特性应用到他们所有的主流产品(例如,Of…

06 算法基础:算法的定义、表现形式(自然语言、伪代码、流程图)、五个特性(有穷性、确定性、可行性、输入、输出)、好算法的设计目标

目录 1 算法的定义 2 算法的三种表现形式 2.1 自然语言 2.2 伪代码 2.3 流程图 3 算法的五个特性 3.1 有穷性 3.2 确定性 3.3 可行性 3.4 输入 3.5 输出 4 好算法的设计目标 4.1 正确性 4.2 可读性 4.3 健壮性 4.4 通用性 4.5 高效率与低存储量 1 算法的定义 …

力姆泰克DMB系列伺服电动缸

力姆泰克DMB系列伺服电动缸 高精度运动,运动平稳,低噪音,高速度 向下翻动查看更多 力姆泰克DMB系列伺服电动缸采用瑞士先进的伺服缸结构设计和进口散件国内组装, 保证力姆泰克伺服电动缸在国内的领先地位. 轧制滚珠丝杠保证伺服…

Google Ads API v18 发布,开发者迎来全新功能与优化

Google 发布了 Google Ads API 第 18 版,为开发者引入了多项新功能和改进。 Google 发布的 Google Ads API 第 18 版引入了增强的工具和功能,使广告主在广告活动优化和性能跟踪方面拥有更多控制权。 主要更新包括: 预算优化建议:新…