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

前言

上一节给大家讲了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.mzph.cn/news/224381.shtml

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

相关文章

十五 动手学深度学习v2计算机视觉 ——全连接神经网络FCN

文章目录 FCN FCN 全卷积网络先使用卷积神经网络抽取图像特征,然后通过卷积层将通道数变换为类别个数,最后通过转置卷积层将特征图的高和宽变换为输入图像的尺寸。 因此,模型输出与输入图像的高和宽相同,且最终输出通道包含了该空…

海思平台isp之ccm标定

文章目录 1、raw图采集2、ccm标定2.1、标定参数配置2.2、标定效果优化2.2.1、优化方式一2.2.2、优化方式二2.2.3、优化方式三1、raw图采集 raw图采集步骤及标准,请参考文章 《海思平台isp之ccm标定》。2、ccm标定 2.1、标定参数配置 (1)图像基本参数 (2)黑电平设置 (…

mac视频调色 DaVinci Resolve Studio 18 中文 for Mac

DaVinci Resolve Studio 18是一款功能强大、专业可靠的视频编辑软件,适用于各种规模的媒体项目制作。无论是独立制片人还是大型制片公司,都可以借助该软件进行高质量的视频创作和后期制作。 得编辑工作更加高效和灵活。 调色和色彩校正:软件…

国外博士论文下载网址

系列文章目录 前言 如果你想补充其他相关网址,请留言 一、pqdtcn 1.1 使用说明 浏览本数据库建议使用chrome浏览器! ProQuest检索平台在今年暑假做了界面升级。为了使您能更快了解升级后的界面功能,ProQuest公司准备了中文版用户使用手册…

【CSS】前端点点点加载小点样式css动画过程实现

对话的 ... 加载动画&#xff0c;直接用 CSS 就可以实现&#xff0c;样式可以自己改&#xff0c;逻辑大差不差 <div class"loading-text"><span class"dot1"></span><span class"dot2"></span><span class&quo…

RabbitMQ入门案例

RabbitMQ 是目前比较主流的MQ消息队列中间件&#xff0c;下面简单总结RabbitMQ入门时所做的一些笔记 1.RabbitMQ 入门案例 需求&#xff1a;用 Java 编写两个程序。发送单个消息的生产者和接收消息并打印出来的消费者 1.1 添加依赖 <!--rabbitmq 依赖客户端--> <de…

C++中的reverse函数

1.实现反转数组。 //头文件 #include <algorithm> //使用方法 reverse(a, an);//n为数组中的元素个数 #include<cstdio> #include<iostream> #include<algorithm> using namespace std; int main() {int a[100];int n,k;cin >> n >> k; …

八大排序(插入排序 | 选择排序 | 冒泡排序)

在我们内存中我们一般会有一些没有顺序的数据&#xff0c;我们成为内排序&#xff0c;而今天分享八大排序的是时间复杂度为O&#xff08;N^2&#xff09;的插入排序&#xff0c;选择排序和教学意义比较强的冒泡排序。 插入排序 这是插入排序的动图&#xff0c;通过动图我们也…

Python3 中常见的数据类型

目录 数字(Number)总结 字符串(String)字符串运算符字符串格式化字符串的截取总结 List&#xff08;列表&#xff09;更新列表删除列表元素列表函数&方法总结 Tuple&#xff08;元组&#xff09;修改元组删除元组总结 Set&#xff08;集合&#xff09;Dictionary&#xff0…

3D点云广义零样本分类的递归循环对比生成网络笔记

1 Title Contrastive Generative Network with Recursive-Loop for 3D point cloud generalized zero-shot classification(Yun Hao, Yukun Su, Guosheng Lin, Hanjing Su, Qingyao Wu)【Pattern Recognition】 2 Conclusion This work aims to facilitate research on 3D poi…

【Spring Boot】内网穿透实现远程调用调试

文章目录 1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址 4.…

机器学习入门笔记

文章目录 背景具体步骤1.环境搭建2.写个demo1.数据处理2.分割数据集3.用模型训练数据&#xff0c;并得到预测结果4.绘制结果5.评估 背景 最近学习了一些关于机器学习的内容&#xff0c;做个笔记。 具体步骤 1.环境搭建 需要用到的工具&#xff1a;pycharm&#xff0c;anaco…

如何了解蜘蛛池蚂蚁SEO

蜘蛛池是一种基于搜索引擎优化的技术手段&#xff0c;通过模拟蜘蛛爬行行为来提高网站在搜索引擎中的排名&#xff0c;从而增加网站的流量和曝光率。 编辑搜图 如何联系蚂蚁seo&#xff1f; baidu搜索&#xff1a;如何联系蚂蚁SEO&#xff1f; baidu搜索&#xff1a;如何联…

【Pytorch】Fizz Buzz

文章目录 1 数据编码2 网络搭建3 网络配置&#xff0c;训练4 结果预测5 翻车现场 学习参考来自&#xff1a; Fizz Buzz in Tensorflowhttps://github.com/wmn7/ML_Practice/tree/master/2019_06_10Fizz Buzz in Pytorch I need you to print the numbers from 1 to 100, excep…

牛客网BC92逆序输出

答案&#xff1a; #include <stdio.h>int main() {int i0, j0;int arr[10]{0};for(i0;i<10;i) //将10个整数存进数组里{scanf("%d",&arr[i]);}for(j9;j>0;j--) //逆序打印{printf("%d ",arr[j]); //若要求最后一个数后面不打印空格…

【Hive】——CLI客户端(bin/beeline,bin/hive)

1 HiveServer、HiveServer2 2 bin/hive 、bin/beeline 区别 3 bin/hive 客户端 hive-site.xml 配置远程 MateStore 地址 XML <?xml version"1.0" encoding"UTF-8" standalone"no"?> <?xml-stylesheet type"text/xsl" hre…

C# WPF上位机开发(利用tcp/ip网络访问plc)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 c# wpf如果是用来开发非标上位机的&#xff0c;那么和plc的通信肯定是少不了的。而且&#xff0c;大部分plc都支持modbus协议&#xff0c;所以这个…

neo4j安装报错:neo4j.bat : 无法将“neo4j.bat”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

neo4j安装报错&#xff1a; neo4j.bat : 无法将“neo4j.bat”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确 保路径正确&#xff0c;然后再试一次。 解决办法&#xff1a; 在环境变量中的&#xff0c;用户…

Shopee ERP:提升电商管理效率的终极解决方案

Shopee ERP&#xff08;Enterprise Resource Planning&#xff0c;企业资源规划&#xff09;是一款专为Shopee卖家设计的集成化电商管理软件。通过使用Shopee ERP系统&#xff0c;卖家可以更高效地管理他们的在线商店&#xff0c;实现库存管理、订单处理、物流跟踪、财务管理、…

优先考虑类型安全的异构容器

在Java中&#xff0c;异构容器是一种可以存储不同类型元素的容器。为了提高类型安全性&#xff0c;可以使用泛型和类型安全的异构容器&#xff0c;而不是传统的非类型安全容器。下面是一个例子&#xff0c;演示如何使用类型安全的异构容器 import java.util.HashMap; import j…