首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

说说RabbitMQ延迟队列实现原理?

编程知识
2024年07月16日 17:36

使用 RabbitMQ 和 RocketMQ 的人是幸运的,因为这两个 MQ 自身提供了延迟队列的实现,不像用 Kafka 的同学那么苦逼,还要自己实现延迟队列。当然,这都是题外话,今天咱们重点来聊聊 RabbitMQ 延迟队列的实现原理,以及 RabbitMQ 实现延迟队列的优缺点有哪些?

很多人知道使用 RabbitMQ 是可以实现延迟队列的,但对于 RocketMQ 自身也提供了延迟队列这件事却持有不同态度,这是因为网上有些资料说 RocketMQ 和 Kafka 没有内置延迟队列。其实这种说法是因为,RocketMQ 在早期版本中确实没有内置延迟队列,但在 4.x 就内置了 18 个级别的延迟队列了(最长支持 2 小时的延迟队列),5.x 就支持随机延迟时间的延迟队列了,所以这里需要特殊强调一下。

1.什么是延迟队列?

延迟队列(Delay Queue)是一种特殊类型的队列,它的主要特点是可以让进入队列的元素在指定的延迟时间之后才被取出进行处理。

延迟队列的主要使用场景有以下这些:

  1. 订单超时处理:在电商系统中,如果用户下单后未在一定时间内支付,订单可能会被自动取消。可以将订单放入延迟队列,在设定的延迟时间(如 30 分钟)后取出处理取消操作。
  2. 任务重试:当某个任务执行失败时,将其放入延迟队列,等待一段时间(如 5 分钟)后重新执行。
  3. 消息延迟发送:某些消息不需要立即发送,而是在指定的延迟时间后发送,例如定时提醒消息。
  4. 缓存过期处理:缓存中的数据可能有一定的有效期,将即将过期的数据放入延迟队列,到期后进行删除或更新操作。

2.延迟任务实现方法

那么延迟队列的实现方式有哪些呢?

延迟队列的实现方式通常有以下几种:

  1. 基于 JDK 提供的 DelayQueue 来实现:它是内存级别的延迟队列,重启应用之后消息会丢失,并且只支持单机版延迟队列,所以一般不用。
  2. 基于 MQ 的延迟队列:例如使用 RabbitMQ 来实现延迟队列,他们适合处理动态和临时延迟任务,不像定时任务一样,适合处理正式的、固定的延迟任务。
  3. 基于定时任务组件实现延迟任务:例如 XXLJob 或 Quartz 等框架来实现延迟任务,他们适合处理固定(执行)频率的延迟任务。

我们通常会使用延迟队列来存储(和实现)延迟消息,所以大部分时候,我们说的延迟队列和延迟消息其实是一回事。

3.使用RabbitMQ实现延迟队列

使用 RabbitMQ 实现延迟队列有以下两种实现方式:

  1. 通过死信队列实现延迟任务:将正常的消息放到没有消息订阅者的消息队列(消息自然就会过期),等消息过期之后会进入死信队列,通过订阅死信队列消费消息,从而实现延迟队列,如下图所示:

image.png

  1. 通过官方提供的延迟插件实现延迟功能

早期大部分公司都会采用第一种方式,而随着 RabbitMQ 3.5.7(2015 年底发布)的延迟插件的发布,因为其使用更简单、更方便,所以它现在才是大家普通会采用的,实现延迟队列的方式。

3.1 实现原理分析

使用延迟插件的实现原理是通过创建一个延迟交换机(Delay Exchange),延迟消息首先会把消息投递到延迟交换机,并不是直接将消息投递业务队列(所以不会立即执行),由延迟交换机控制消息在延迟一段时间后,再将消息投递到真正的队列中进行消费,从而实现延迟队列,它的实现流程如下图所示:
image.png

其中 Mnesia 可以理解为基于文件存储的数据库。

3.2 优缺点分析

使用死信队列实现延迟任务有个缺点,它不能实现随机延迟任务,每个无消费者的队列上只能设置一个 ttl(消息过期时间),所以只能实现固定过期时间的延迟任务。

使用延迟插件实现延迟任务有以下两个缺点:

  1. 消息丢失问题:消息在真的被投递到目标消息队列之前,是存放在接收到了这个消息的服务端本地的 Mnesia 里面。也就是说,如果这个时候还没有刷新磁盘,那么消息就会丢失;如果这个节点不可用了,那么消息也同样会丢失。
  2. 高并发问题:这种实现方式不支持高并发场景,因为它只有一个延迟交换机,当高并发或数据量比较大时执行效率就会比较低。

课后思考

如何解决 RabbitMQ 延迟插件造成的这两个问题?如何实现 Kafka 的延迟队列?

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

From:https://www.cnblogs.com/vipstone/p/18305883
本文地址: http://www.shuzixingkong.net/article/119
0评论
提交 加载更多评论
其他文章 Pybind11和CMake构建python扩展模块环境搭建
使用pybind11的CMake模板来创建拓展环境搭建 从Github上下载cmake_example的模板,切换分支,并升级pybind11子模块到最新版本 拉取pybind11使用cmake构建工具的模板仓库 git clone --recursive https://github.com/mr
Pybind11和CMake构建python扩展模块环境搭建
写了一个json小工具,希望大家体验(Mac平台)
用rust写了一个json小工具“JSON PICKER”,欢迎大家试用: https://github.com/davelet/json-picker/releases/tag/V0.2 动机是平常开发的时候,经常遇到大段json,里面的很多字段是不需要的。 我所在的项目组在接口对接上出现了rep
写了一个json小工具,希望大家体验(Mac平台) 写了一个json小工具,希望大家体验(Mac平台)
Java JVM——12. 垃圾回收理论概述
1.前言 1.1 什么是垃圾? 在提到什么是垃圾之前,我们先看下面一张图: 从上图我们可以很明确的知道,Java 和 C++ 语言的区别,就在于垃圾收集技术和内存动态分配上,C++ 语言没有垃圾收集技术,需要我们手动的收集。 垃圾收集,不是 Java 语言的伴生产物,早在1960年,第一门
Java JVM——12. 垃圾回收理论概述 Java JVM——12. 垃圾回收理论概述 Java JVM——12. 垃圾回收理论概述
.NET开源、简单、实用的数据库文档生成工具
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、简单、实用的数据库文档(字典)生成工具,该工具支持CHM、Word、Excel、PDF、Html、XML、Markdown等多文档格式的导出:DBCHM。 支持的数据库 SqlServer、MySQL、Oracle、Postg
.NET开源、简单、实用的数据库文档生成工具 .NET开源、简单、实用的数据库文档生成工具 .NET开源、简单、实用的数据库文档生成工具
美团VS饿了么,到底谁更胜一筹?
最近啊,收到一个粉丝的投稿,我发现他在美团和饿了么都去面试过。 这俩企业大家应该都经常用吧,咱点外卖的时候,我有时候就琢磨,到底他俩谁更厉害点。 今天咱们就瞅瞅,在面试这块儿谁更难一些。 (目前都只有一面的情况,要是想要后续的,私聊我发给你哈) 美团 一面 自我介绍 项目做完了吗?背景是什么?项目初
yolov5 损失函数代码详解
模型的损失计算包括3个方面,分别是: 1. 定位损失 2. 分类损失 3. 置信度损失 本篇主要讲解yolov5中损失计算的实现,包括损失的逻辑实现,张量操作的细节等。
yolov5 损失函数代码详解 yolov5 损失函数代码详解 yolov5 损失函数代码详解
Linux 提权-密码搜寻
本文通过 Google 翻译 Password Hunting – Linux Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释补充。 导航 0 前言 1 密码搜寻 – 文件名和文件内容 1.1 寻找有趣的文件名 1.2 寻找有趣的
Linux 提权-密码搜寻 Linux 提权-密码搜寻 Linux 提权-密码搜寻
Apache基于IP和端口
Apache基于IP 步骤1:添加并配置虚拟网卡 添加虚拟网卡:通常在虚拟机环境中,可以通过虚拟机软件(如VMware或VirtualBox)的网络设置来添加额外的网络适配器。 配置IP地址:编辑/etc/sysconfig/network-scripts/ifcfg-ethX文件,,并将它们设置为
Apache基于IP和端口 Apache基于IP和端口 Apache基于IP和端口