Java小案例-RocketMQ的11种消息类型,你知道几种?(延迟消息)

news2024/9/23 5:31:48

前言

上一节给大家讲了Rocket的顺序消息,这一节和大家聊一下延迟消息,关于顺序消息大家可以点下面这个链接直接看

RocketMQ的延迟消息

延迟消息

延迟消息就是指生产者发送消息之后,消息不会立马被消费,而是等待一定的时间之后再被消息

RocketMQ的延迟消息用起来非常简单,只需要在创建消息的时候指定延迟级别,之后这条消息就成为延迟消息了

Message message = new Message("sanyouTopic", "java日记 0".getBytes());
//延迟级别
message.setDelayTimeLevel(1);

虽然用起来简单,但是背后的实现原理还是有点意思,我们接着往下看

RocketMQ延迟消息的延迟时间默认有18个级别,不同的延迟级别对应的延迟时间不同

RocketMQ内部有一个Topic,专门用来表示是延迟消息的,叫SCHEDULE_TOPIC_XXXX,XXXX不是占位符,就是XXXX

RocketMQ会根据延迟级别的个数为SCHEDULE_TOPIC_XXXX这个Topic创建相对应数量的队列

比如默认延迟级别是18,那么SCHEDULE_TOPIC_XXXX就有18个队列,队列的id从0开始,所以延迟级别为1时,对应的队列id就是0,为2时对应的就是1,依次类推

SCHEDULE_TOPIC_XXXX这个Topic有什么作用呢?

这就得从消息存储时的一波偷梁换柱的骚操作了说起了

当服务端接收到消息的时候,判断延迟级别大于0的时候,说明是延迟消息,此时会干下面三件事:

  • 将消息的Topic改成SCHEDULE_TOPIC_XXXX

  • 将消息的队列id设置为延迟级别对应的队列id

  • 将消息真正的Topic和队列id存到前面提到的消息存储时的额外信息中

之后消息就按照正常存储的步骤存到CommitLog文件中

由于消息存到的是SCHEDULE_TOPIC_XXXX这个Topic中,而不是消息真正的目标Topic中,所以消费者此时是消费不到消息的

举个例子,比如有条消息,Topic为sanyou,所在的队列id = 1,延迟级别 = 1,那么偷梁换柱之后的结果如下图所示

代码如下

所以从上分析可以得出一个结论

所有RocketMQ的延迟消息,最终都会存储到SCHEDULE_TOPIC_XXXX这个Topic中,并且同一个延迟级别的消息在同一个队列中

在存消息偷梁换柱之后,实现延迟消费的最关键的一个步骤来了

BocketMQ在启动的时候,除了为每个延迟级别创建一个队列之后,还会为每个延迟级别创建一个延迟任务,也就相当于一个定时任务,每隔100ms执行一次

这个延迟任务会去检查这个队列中的消息有没有到达延迟时间,也就是不是可以消费了

前面的结论,每个队列都有一个ConsumeQueue文件,可以通过ConsumeQueue找到这个队列中的消息

一旦发现到达延迟时间,可以消费了,此时就会从这条消息额外存储的消息中拿到真正的Topic和队列id,重新构建一条新的消息,将新的消息的Topic和队列id设置成真正的Topic和队列id,内容还是原来消息的内容

之后再一次将新构建的消息存储到CommitLog中

由于新消息的Topic变成消息真正的Topic了,所以之后消费者就能够消费到这条消息了

所以,从整体来说,RocketMQ延迟消息的实现本质上就是最开始消息是存在SCHEDULE_TOPIC_XXXX这个中转的Topic中

然后会有一个类似定时任务的东西,不停地去找到这个Topic中的消息

一旦发现这个消息达到了延迟任务,说明可以消费了,那么就重新构建一条消息,这条消息的Topic和队列id都是实际上的Topic和队列id,然后存到CommitLog

之后消费者就能够在目标的Topic获取到消息了

总结

RocketMQ的延迟消息是一种特殊的消息类型,当消息写入到Broker后,不能立刻被消费者消费,需要等待指定的时长后才可被消费处理。这种消息的延迟时长不支持随意时长的延迟,是通过特定的延迟等级来指定的。RocketMQ默认支持18个等级的延迟消息,延时等级定义在RocketMQ服务端的MessageStoreConfig类中的特定变量中。

在实际应用中,不使用定时器,利用RocketMQ的延迟消息可以实现定时任务的功能,适用于一些特定的场景,如电商交易系统的订单超时未支付自动取消订单等。

其实现原理主要是消息在RocketMQ Broker端的流转过程中,对延迟消息进行特殊处理,计算这条延迟消息需要在什么时候进行投递。投递时间等于消息存储时间加上延迟级别对应的时间。

联系方式

关于文章中大家有任何疑问可以通过关注公众号《编程乐学》进行留言,同时,公众号还有更多有趣的项目以及关于学习编程的笔记资料大家可以看看,欢迎大家进行留言。

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

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

相关文章

JMeter下载与安装

文章目录 前言一、安装java环境(JDK下载与安装)二、JMeter下载三、JMeter安装1.解压缩2.配置环境变量 四、JMeter启动(启动成功则代表JMeter安装成功)五、JMeter汉化(将JMeter修改成中文)1.方法一&#xff…

【Linux】内核结构

一、Linux内核结构介绍 Linux内核结构框图 二、图解Linux系统架构 三、驱动认知 1、为什么要学习写驱动2、文件名与设备号3、open函数打通上层到底层硬件的详细过程 四、Shell Shell脚本 一、Linux内核结构介绍 Linux 内核是操作系统的核心部分,它负责管理系…

【Android】MVC与MVP的区别,MVP网络请求实践

一、MVC模式 目录 一、MVC模式二、MVP模式 1、MVP的简单应用 1.1 导入相关依赖包并设置权限1.2 实现Model1.2 实现Presenter1.3 实现View1.4分析项目结构和绑定过程1.5效果展示 2、MVP结合RxJava 一、MVC模式 MVC(Model(模型)——View(视图)——Controller(控制…

三层交换,DHCP的详解与VRRP

目录 一、三层交换 1、三层交换机的作用: 2.vlan的虚拟接口vlanif(ifinterface接口) 3.三层交换机实验 4.拓展实验​编辑 二、DHCP 1.自动获取ip地址: 2.DHCP的好处: 3.分配方式: 4.举例&#xff…

6.rk3588获取摄像头和激光雷达数据(用线程根据时间同步)

文件夹结构如下: 如果没有特殊说明,我们将py文件写在该路径里面。 保存数据的路径如下: ---img_lidar_save ---2023-12-13(根据日期自动生成当天保存数据的文件夹) ---camera_data(相机数据文件夹) ---image(保存相加…

C++1114新标准——模板模板参数(Template Template Parameter)、using

系列文章目录 C11&14新标准——Variadic templates(数量不定的模板参数) C11&14新标准——Uniform Initialization(统一初始化)、Initializer_list(初始化列表)、explicit C11&14新标准—— d…

SpringBoot 究竟是如何跑起来的

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《SpringBoot》。🎯🎯 &…

怎么把文件转成附件放在公众号里?这篇教程给你详细说清楚

文件转附件,其实就是把文件上传到某个网站,获得文件的下载链接,从而放到文章或者其他地方供读者下载使用。因为公众号并不支持直接在文章里面添加下载链接(至少订阅号不行),所以把文件转成下载链接的方式并…

怎么制作GIF动图?教你这几个简单方法

怎么制作gif动图?GIF动图是一种非常有趣且实用的图片格式,它能够以短小精悍的方式展示动画效果,因此在社交媒体和聊天应用中备受追捧。本文将向您介绍几种制作GIF动图的方法,让您轻松制作出自己的动图。 GIF动图制作方法一&#x…

Spark编程实验一:Spark和Hadoop的安装使用

一、目的与要求 1、掌握在Linux虚拟机中安装Hadoop和Spark的方法; 2、熟悉HDFS的基本使用方法; 3、掌握使用Spark访问本地文件和HDFS文件的方法。 二、实验内容 1、安装Hadoop和Spark 进入Linux系统,完成Hadoop伪分布式模式的安装。完成Ha…

【开源项目】智慧水厂—经典开源项目实景三维数字孪生智慧水厂

智慧水务可视化平台是以物联网IOT技术为核心,以数据库系统为支撑,以城市水资源安全提升和建造智能化为目标的智慧水务体系。飞渡科技利用数字孪生技术结合物联网IOT技术,建立起多个基础数据及管理层级矩阵,可以跨部门、跨层级进行…

【Java 集合】ConcurrentLinkedQueue

在日常中, 我们用到的数据结构有很多: 数组, 链表, 树等, 而在这些结构中, 还有一个叫做队列的存在。 和其他的集合相同, Java 原生提供了不同的实现。 而如果我们需要一个线程安全的队列的话, 可以基于实际的场景进行选择, 比如基于数组实现同时操作上会阻塞的 ArrayBlockingQ…

我们为什么经常使用List list = new ArrayList<>() 而不是ArrayListlist = new ArrayList<>()

为什么不直接去Arraylist list new Arraylist();而是直接通过List list new ArrayList();使用接口的好处 在Java中,使用List接口声明ArrayList类的变量是一种良好的编程实践,因为这符合面向接口编程的原则。面向接口编程是一种编程范式&…

canvas基本绘制对象

目录 绘制画布 设置画布 绘制圆形 绘制矩形填充渐变色 绘制文字及文字样式 绘制画布 <canvas id"canvas" width"800" height"600"></canvas> 设置画布 //获得画布元素var canvasdocument.getElementById(canvas);var ctxca…

GitHub Universe 2023 Watch Party in Shanghai:开源开发者日盛会

目录 前言GitHub Universe 2023的背景开源开发者日活动亮点本次参会的意义活动日程最后 前言 作为全球最大的代码托管平台&#xff0c;GitHub每年都会举办一场令开源开发者们翘首以待的盛会——GitHub Universe&#xff0c;今年也不例外&#xff0c;就在2023年的12月10日&…

算法训练营Day14

#Java #二叉树层次遍历 #反转二叉树 开源学习资料 二叉树的层次遍历&#xff1a;力扣题目链接 二叉树的层次遍历很好理解&#xff1a; 就是从根结点一层一层地往下遍历&#xff08;同一层&#xff0c;从左到右&#xff09;&#xff1a; 迭代的方式很好理解&#xff1a;就是…

computed 和 watch 的奇妙世界:让数据驱动你的 Vue 应用(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

docker部署go gin框架 Windows环境

目录 文章目的是什么 环境介绍 Windows 环境下 docker 部署 go gin 详细步骤 运行容器时因为挂载文件可能会出现的问题 直接部署gin&#xff08;跳过运行容器时因为挂载文件可能会出现的问题&#xff09; 文章目的是什么 假设我们学习了 go 语言&#xff0c;在 Windows(本…

精选硬件连通性测试工具:企业如何做出明智选择

在当今数字化的商业环境中&#xff0c;企业的硬件连通性至关重要。选择适用的硬件连通性测试工具是确保网络和设备协同工作的关键一步。本文将探讨企业在选择硬件连通性测试工具时应考虑的关键因素&#xff0c;以帮助其做出明智的决策。 1. 功能全面性&#xff1a;首要考虑因素…

PHP微信朋友圈广告植入源码 +提供高效的广告植入解决方案,助力微信朋友圈广告推广

源码介绍 可以无限制帮用户开户&#xff0c;也可以理解为多用户版。 可以管理用户发布文章条数&#xff0c;也可以无限制发布。 用户可以上传多个广告&#xff0c;每个广告分别进行统计展示及点击。 用户一键植入&#xff0c;不用粘贴网址&#xff0c;每篇文章会 分别统计展示…