RocketMQ简介

news2025/2/22 0:36:00

目录

MQ介绍

MQ的优点和缺点

各种MQ产品的比较

消息发送者步骤分析

消息消费者步骤分析

顺序消息

延时消息

事务消息

1)事务消息发送及提交

2)事务补偿

3)事务消息状态

使用限制

重试队列

重试配置

怎么保证消息消费的时候0丢失?

怎么解决重试幂等性问题?

死信队列

死信队列具有以下特性:


MQ介绍

1.1 为什么要用MQ

消息队列是一种“先进先出”的数据结构

消息队列是一种“先进先出”的数据结构其应用场景主要包含以下3个方面

  • 应用解耦

  • 流量削峰

  • 数据分发

1、 系统的耦合性越高,容错性就越低。以电商应用为例,用户创建订单后,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统出了故障或者因为升级等原因暂时不可用,都会造成下单操作异常,影响用户使用体验。

 

       使用消息队列解耦合,系统的耦合性就会降低了。比如物流系统发生故障,需要几分钟才能来修复,在这段时间内,物流系统要处理的数据被缓存到消息队列中,用户的下单操作正常完成。当物流系统恢复后,补充处理存在消息队列中的订单消息即可,终端系统感知不到物流系统发生过几分钟故障。

2、应用系统如果遇到系统请求流量的瞬间猛增,有可能会将系统压垮。有了消息队列可以将大量请求缓存起来,分散到很长一段时间处理,这样可以大大提到系统的稳定性和用户体验。

 一般情况,为了保证系统的稳定性,如果系统负载超过阈值,就会阻止用户请求,这会影响用户体验,而如果使用消息队列将请求缓存起来,等待系统处理完毕后通知用户下单完毕,这样总比不能下单体验要好。

3、通过消息队列可以让数据在多个系统之间进行流通。数据的产生方不需要关心谁来使用数据,只需要将数据发送到消息队列,数据使用方直接在消息队列中直接获取数据即可

 使用mq

MQ的优点和缺点

优点:解耦、削峰、数据分发

缺点包含以下几点:

  • 系统可用性降低

    系统引入的外部依赖越多,系统稳定性越差。一旦MQ宕机,就会对业务造成影响。

    如何保证MQ的高可用?

答:使用 同步双写 集群模式 这就保证了消息的 安全性、不易丢失,但是会 损耗大概百分之十的性能

  • 系统复杂度提高

    MQ的加入大大增加了系统的复杂度,以前系统间是同步的远程调用,现在是通过MQ进行异步调用。

    如何保证消息没有被重复消费?怎么处理消息丢失情况?那么保证消息传递的顺序性?

答:

发送消息的时候指定 队列选择器,把要 保证顺序的消息 发送到 同一个队列 中,利用一个 队列天然有序的特性 来保证消息的有序性消费者使用 orderly 的监听器

总结: 顺序消息 就是在生产者 指定MessageQueueSelector消费者 去指定 MessageListenerOrderly

  • 一致性问题

    A系统处理完业务,通过MQ给B、C、D三个系统发消息数据,如果B系统、C系统处理成功,D系统处理失败。

    如何保证消息数据处理的一致性?

答:将处理过的消息存到数据库中的trade_mq_consumer_log 表中,我们拿到一条消息 不是拿来立马就进行消费 而是先判断这个消息是否被处理过,如果被处理过 就无须再次处理,否则 就会出现幂等性问题 说白了 避免消息重复消费。(使用数据库的 乐观锁 更改消息的状态 避免并发问题)

各种MQ产品的比较

消息发送者步骤分析

1.创建消息生产者producer,并制定生产者组名
2.指定Nameserver地址
3.启动producer
4.创建消息对象,指定主题Topic、Tag和消息体
5.发送消息
6.关闭生产者producer

消息消费者步骤分析

1.创建消费者Consumer,制定消费者组名
2.指定Nameserver地址
3.订阅主题Topic和Tag
4.设置回调函数,处理消息
5.启动消费者consumer

顺序消息

        消息有序指的是可以按照消息的发送 顺序来消费(FIFO)。RocketMQ可以严格的保证消息有序,可以分为分区有序或者全局有序。

        顺序消费的原理解析,在默认的情况下消息发送会采取Round Robin轮询方式把消息发送到不同的queue(分区队列);而消费消息的时候从多个queue上拉取消息,这种情况发送和消费是不能保证顺序。但是如果控制发送的顺序消息只依次发送到同一个queue中,消费的时候只从这个queue上依次拉取,则就保证了顺序。当发送和消费参与的queue只有一个,则是全局有序;如果多个queue参与,则为分区有序,即相对每个queue,消息都是有序的。

延时消息

 RocketMq并不支持任意时间的延时,需要设置几个固定的延时等级,从1s到2h分别对应着等级1到18  (共18个等级)

事务消息

 流程分析

        事务消息 producer 发送给MQ的消息是带有事务控制的, 发的消息需要生产者一个事务的提交 如果 消息发送给MQ Server 但是没有提交事务 那么这个消息是不能被消费者消费的 ,这种由于生产者没有提交 而导致消费者不可消费的消息 我们称之为 half 消息,half 消息发送完了之后重试 MQ 会给生产者一个反馈 消息已经收到了,然后生产者执行本地的事务,当你把本地事务执行完了之后 生产者再对half消息执行一个 Commit 或者 Rollback , 当做了Commit 操作 ,则消息可以被消费者消费了,如果执行了Rollback ,MQ Server 就会把这个消息删除掉,消费者就接受不到这个消息了,如果在做提交 和 回滚操作时 失败了 或者超时了 这个时候 MQ Server 会对消息做一个回查 就是一个Check Back 通过回调方法检查消息的状态 通过检查状态 再对消息进行 处理(提交或回滚)

其中分为两个流程:正常事务消息的发送及提交、事务消息的补偿流程

1)事务消息发送及提交

(1) 发送消息(half消息)。

(2) 服务端响应消息写入结果。

(3) 根据发送结果执行本地事务(如果写入失败,此时half消息对业务不可见,本地逻辑不执行)。

(4) 根据本地事务状态执行Commit或者Rollback(Commit操作生成消息索引,消息对消费者可见)

2)事务补偿

(1) 对没有Commit/Rollback的事务消息(pending状态的消息),从服务端发起一次“回查”

(2) Producer收到回查消息,检查回查消息对应的本地事务的状态

(3) 根据本地事务状态,重新Commit或者Rollback

其中,补偿阶段用于解决消息Commit或者Rollback发生超时或者失败的情况。

3)事务消息状态

事务消息共有三种状态,提交状态、回滚状态、中间状态:

  • TransactionStatus.CommitTransaction: 提交事务,它允许消费者消费此消息。

  • TransactionStatus.RollbackTransaction: 回滚事务,它代表该消息将被删除,不允许被消费。

  • TransactionStatus.Unknown: 中间状态,它代表需要检查消息队列来确定状态。

使用限制

  1. 事务消息 不支持 延时消息 和 批量消息。

  2. 为了避免单个消息被检查太多次而导致半队列消息累积,我们默认将单个消息的检查次数限制为 15 次,但是用户可以通过 Broker 配置文件的 transactionCheckMax参数来修改此限制。如果已经检查某条消息超过 N 次的话( N = transactionCheckMax ) 则 Broker 将丢弃此消息,并在默认情况下同时打印错误日志。用户可以通过重写 AbstractTransactionCheckListener 类来修改这个行为。

  3. 事务消息将在 Broker 配置文件中的参数 transactionMsgTimeout 这样的特定时间长度之后被检查。当发送事务消息时,用户还可以通过设置用户属性 CHECK_IMMUNITY_TIME_IN_SECONDS 来改变这个限制,该参数优先于 transactionMsgTimeout 参数。

  4. 事务性消息可能不止一次被检查或消费。

  5. 提交给用户的目标主题消息可能会失败,目前这依日志的记录而定。它的高可用性通过 RocketMQ 本身的高可用性机制来保证,如果希望确保事务消息不丢失、并且事务完整性得到保证,建议使用同步的双重写入机制。

  6. 事务消息的生产者 ID 不能与其他类型消息的生产者 ID 共享。与其他类型的消息不同,事务消息允许反向查询、MQ服务器能通过它们的生产者 ID 查询到消费者。

重试队列

RocketMQ消费端默认有重试机制,消费端重试分为两种情况

  1. 异常重试:由于Consumer端逻辑出现了异常,导致返回了RECONSUME_LATER状态,那么Broker就会在一段时间后尝试重试。

  2. 超时重试:如果Consumer端处理时间过长,或者由于某些原因线程挂起,导致迟迟没有返回消费状态,Broker就会认为Consumer消费超时,此时会发起超时重试。

设置重试时间与次数:

可在broker.conf文件中配置Consumer端的重试次数和重试时间间隔

第几次重试与上次重试的间隔时间第几次重试与上次重试的间隔时间
110 秒97 分钟
230 秒108 分钟
31 分钟119 分钟
42 分钟1210 分钟
53 分钟1320 分钟
64 分钟1430 分钟
75 分钟151 小时
86 分钟162 小时

如果消息重试 16 次后仍然失败,消息将不再投递。如果严格按照上述重试时间间隔计算,某条消息在一直消费失败的前提下,将会在接下来的 4 小时 46 分钟之内进行 16 次重试,超过这个时间范围消息将不再重试投递。

注意: 一条消息无论重试多少次,这些重试消息的 Message ID 不会改变。

重试配置

集群消费方式下,消息消费失败后期望消息重试,需要在消息监听器接口的实现中明确进行配置(三种方式任选一种):

  • 返回 RECONSUME_LATER (推荐)

  • 返回 Null

  • 抛出异常

注意1:只有在消息模式为MessageModel.CLUSTERING集群模式时,Broker才会自动进行重试,广播消息是不会重试的。

注意2:由于MQ的重试机制,难免会引起消息的重复消费问题。比如一个ConsumerGroup中有两个,Consumer1和Consumer2,以集群方式消费。假设一条消息发往ConsumerGroup,由Consumer1消费,但是由于Consumer1消费过慢导致超时,如果Broker将消息发送给Consumer2去消费,这样就产生了重复消费问题。因此,使用MQ时应该对一些关键消息进行幂等去重的处理。

怎么保证消息消费的时候0丢失?

答:Rocketmq默认就有重试机制,如果第一次消费的时候,broker收到的回应是(ConsumeConcurrentlyStatus.RECONSUME_LATER),那么这条消息不会丢失,会进入重试队列,重试的次数与重试的时间可以配置,如果重试的次数超过配置的次数,那么这条消息没有丢失,但是放入死信队列

怎么解决重试幂等性问题?

答:如果重试很有可能出现幂等性问题,需要业务逻辑做配合,比如可以先判断数据库的状态,然后根据数据库的状态,做对应的处理

其实 就是 占坑 思想 , 比如 setnx 多个消费者 只有第一个消费者 占坑成功 可以消费

死信队列

当一条消息初次消费失败,消息队列 RocketMQ 会自动进行消息重试,达到最大重试次数后,若消费依然失败,则表明消费者在正常情况下无法正确地消费该消息。此时,消息队列 RocketMQ 不会立刻将消息丢弃,而是将其发送到该消费者对应的特殊队列中。

在消息队列 RocketMQ 版中,这种正常情况下无法被消费的消息称为死信消息(Dead-Letter Message),存储死信消息的特殊队列称为死信队列(Dead-Letter Queue)。


死信消息具有以下特性:
1:不会再被之前的消费者正常消费。
2:有效期与正常消息相同,均为 3 天,3 天后会被自动删除。因此,请在死信消息产生后的 3 天内及时处理。


死信队列具有以下特性:


1:一个死信队列对应一个 Group ID, 而不是对应单个消费者实例。
2:如果一个 Group ID 未产生死信消息,消息队列 RocketMQ 便不会为其创建相应的死信队列。
3:一个死信队列包含了对应 Group ID 产生的所有死信消息,不论该消息属于哪个 Topic。
4:消息队列 RocketMQ 版控制台提供对死信消息的查询、重发的功能。

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

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

相关文章

Java——《面试题——MyBatis篇》

前文 java——《面试题——基础篇》 Java——《面试题——JVM篇》 Java——《面试题——多线程&并发篇》 Java——《面试题——Spring篇》 目录 前文 1、什么是MyBatis 2、说说MyBatis的优点和缺点 3、#{}和${}的区别是什么? 4、当实体类中的属性名和…

Flask框架制作读取txt文本网页

Pycharm demo项目 app2.py&#xff08;运行&#xff09; index2.html &#xff08;网页&#xff09; 网页访问地址&#xff1a; http://127.0.0.1:5000 网页画面 核心代码(网页) 点击按钮弹窗选择 txt 文件&#xff08;index2.html&#xff09; <form method"post&…

探索CSS中的粘性定位:解锁网页布局的新可能

这篇文章详细解释了CSS中的sticky定位方式&#xff0c;并讲解了它的工作原理。 CSS中的sticky定位有很好的浏览器支持&#xff0c;但许多开发者并没有使用它。原因有两方面&#xff1a;一是等待浏览器支持的时间太长&#xff0c;导致这个特性被遗忘&#xff1b;二是大部分开发…

OpenCV项目开发实战--一步一步介绍使用 OpenPose 进行基于深度学习的人体姿势估计--C++/Python源码

文末附基于Python和C++两种方式实现的测试代码下载链接 在本教程中,使用 OpenCV 进行基于深度学习的人体姿态估计。我们将详细说明如何在您自己的应用程序中使用预训练 Caffe 模型。 1.姿态估计(又名关键点检测) 姿态估计是计算机视觉中的一个普遍问题,我们在其中检测物体…

西门子Mendix入门

首先进入网址Mendix 点击下方sign up进入带注册页面 我的注册成功后需要等会才能完成注册&#xff0c;我是下午开始注册的&#xff0c;晚上九点半的时候就可以登陆了 点击右上方create Apps 之后进入到这个页面选择应用程序模板 这里我们搜索Task选择第一个 单击Select Templa…

【Arduino+ESP32专题】Visual Studio Code界面重置为默认状态

在使用Visual Studio Code进行编程的时候&#xff0c;有时不小心把某些状态栏或功能框关闭了&#xff0c;不知道从哪里再次打开。因此有一个办法是曲线救国&#xff0c;可以让Visual Studio Code界面重置为默认状态就行了。 方式1 选择右上角Open Settings(UI)图标 打开文档把…

GC相关的

1、判断对象是否为垃圾的算法 引用计数算法可达性分析算法 引用计数算法 判断的标准&#xff1a; 通过判断对象的引用数量来决定对象是否可以被回收。 每个对象实例都有一个引用计数器&#xff0c;被引用则1&#xff0c;完成引用则-1。 任何引用计数为0的对象实例可以被当…

操作系统-I/O管理-I/O系统(设备独立性软件)

目录 一、假脱机技术(SPOOLing技术) 二、设备的分配与回收 2.1设备分配考虑因素 设备的固有属性 设备分配算法 设备分配中的安全性 2.2静态分配和动态分配 2.3设备分配管理中的数据结构 DTC COCT CHCT SDT 三、缓冲区管理 3.1单缓冲 3.2 双缓冲 ​3.2循环缓冲 3.…

1746_Perl中面向对象的目录处理模块

全部学习汇总&#xff1a; GreyZhang/perl_basic: some perl basic learning notes. (github.com) 说起来我还不懂Perl的面向对象编程技术&#xff0c;只是在前阵子看到了书中提到了一句&#xff0c;用到了一个例子。今天看书的时候又看到了类型形势的代码&#xff08;代码中很…

25利用 灰色预测模型预测发电量(附matlab程序)

1.简述 学习目标&#xff1a; 灰色预测模型预测发电量 根据原始发电量数据预测需要年份的发电量 发电量预测是电力系统规划与运行的基础,是电力市场运作中的重要组成部分.目前,对发电量预测的研究已经比较深入,常用的发电量预测方法有:灰色预测法,线性回归模型,自回归移动平均模…

软件测试(1)

软件测试就是用来验证产品特性是否满足用户需求 调试是发现并解决软件中的缺陷 开发人员编码阶段进行 测试是用来发现软件中的缺陷 测试人员&#xff0c;开发人员&#xff08;单元测试&#xff0c;集成测试&#xff09; 测试贯穿于整个软件的生命周期&#xff0c;但是调…

免费在线压缩图片的网站

1. TinyPNG - 这是一个非常受欢迎的在线图片压缩网站,可以压缩 PNG 和 JPG 图片,保证无损压缩。 网址&#xff1a;TinyPNG – Compress WebP, PNG and JPEG images intelligently 2. Compressor.io - 这也是一个很好的在线图片压缩工具,可以批量上传和压缩图片,支持 PNG, JPG 和…

逆向Android开发工程,抓包!抓包!学习哪里?

抓包是什么&#xff1f; 在Android逆向工程中&#xff0c;抓包是一项重要的技术&#xff0c;用于获取手机应用程序与服务器之间的通信数据。通过抓包&#xff0c;可以分析应用程序的网络请求&#xff0c;获取请求的URL、参数、响应数据等信息&#xff0c;对应用程序的行为进行…

JavaSE进阶--注解

文章目录 前言一、概念二、使用实例1、Junit测试中2、JDK内置注解 三、自定义注解1、注解声明2、注解配置参数2.1 配置参数的类型&#xff1a;2.2 注意2.3 两个概念 3、使用注解 四、元注解1、Retention1.1 RetentionPolicy.SOURCE1.2 RetentionPolicy.CLASS1.3 RetentionPolic…

千万不要在简历里写精通C++,没人能真正精通C++

任何说自己很懂C的人可能都是在夸大其词。 我想你可能已经注意到了&#xff0c;是的&#xff0c;今天的大多数程序员都在使用Python、Rust、Go或是其他新的编程语言。大部分人已经不再需要掌握C、C等古老的编程语言了&#xff0c;甚至很多程序员已经从手动编码开始向AI编码转型…

el-select 触底分页+远程搜索

文章目录 前言一、el-select 触底分页远程搜索1.封装触底自定义指令2.在 mian.js 引入封装好的自定义指令3.在组件中进行使用 总结 前言 大部分情况下使用 el-select 的时候&#xff0c;el-options 中 options 的值都是后端接口给的数据&#xff0c;直接赋值就可以了。但是有的…

(8版本)mysql数据库安装教程(自用保存)

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: mysql 参考csdn大神们的文章&#xff0c; 总结出来的详细用法~~~ 目录 文章目录 一、下载MySQL8.0.33 二、配置初始化文件my.ini(重点) 三、初始化MySQL 四、安装MySQL服务并启动 修改密码 4.1 安装…

akima 插值拟合算法 Python/C++版本

目录 前言Akima简介Akima优势 算法的代码实现python版C 版代码解析1代码解析2代码解析3 结果测试 前言 鉴于CSDN上Akima算法文章大部分要VIP观看或者下载&#xff0c;即使是付费也有质量不佳&#xff0c;浪费Money也浪费时间。 笔者更具查到的资料分享给大家。 Akima简介 Ak…

C++技能系列 ( 5 ) - 详解函数入参/返回参使用(值传递/引用传递/指针传递/智能指针传递)

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 期待动动小手&#xff0c;点击关注哦&#xff01;&#xff01;&#xff01; 当你休息的时候&#xff0c;一定要想到别人还在奔跑。 When you rest, we must thin…

数据库相关

1、主要考点思维导图 2、如何设计一个关系型数据库 存储管理&#xff1a;数据逻辑关系转为物理存储关系。 缓存机制&#xff1a;优化执行效率。 SQL解析&#xff1a;将Sql语句进行解析。 日志管理&#xff1a;记录操作。 权限划分&#xff1a;多用户管理。 容灾机制&…