1、RocketMQ 核心架构拆解

1. 为什么要使用消息队列?

消息队列(MQ)是分布式系统中不可或缺的中间件,主要解决系统间的解耦、异步和削峰填谷问题。

  • 解耦:生产者和消费者通过消息队列通信,彼此无需直接依赖,极大提升系统灵活性和可维护性。例如订单系统下单后,短信、积分等服务都可通过订阅消息队列实现解耦。
  • 异步:将耗时操作(如发短信、邮件)异步处理,主流程快速响应,提升用户体验。
  • 削峰填谷:高并发场景下,消息队列作为缓冲区,将瞬时高流量转化为后端可承受的平稳流量,防止系统崩溃。

副作用:引入消息队列会带来系统复杂度提升、可用性降低、消息重复、顺序性、分布式事务、消息堆积等问题,需要配套机制解决。

2. 为什么选择 RocketMQ?

RocketMQ 具备高吞吐、低延迟、分布式高可用、消息可靠性强、支持大规模消息堆积等特点,尤其适合金融、电商等高并发高可靠场景。其在阿里双十一等极端场景下经受住了考验。

  • 单机吞吐量十万级,支持亿级消息堆积
  • 分布式架构,主从高可用
  • 消息可靠性高,可配置参数实现 0 丢失
  • 功能完善,支持顺序、延时、事务等多种消息类型
  • 源码开放,易于二次开发

3. RocketMQ 优缺点

  • 优点
    • 单机吞吐量高,分布式高可用
    • 消息可靠性强,支持主从同步
    • 功能丰富,支持顺序、延时、事务、死信队列等
    • 支持亿级消息堆积,性能稳定
    • 源码开放,易于定制

4. 消息队列的消息模型

  • 队列模型:生产者将消息发送到队列,多个消费者竞争消费,每条消息只会被一个消费者消费,适合任务分发、负载均衡场景。
    在这里插入图片描述

  • 发布/订阅模型:生产者将消息发送到主题(Topic),多个消费者订阅同一主题,每个消费者都能收到全量消息,适合广播、事件通知场景。
    -在这里插入图片描述

5、RocketMQ 核心概念详解

在这里插入图片描述

  • Message(消息):要传输的信息。每条消息必须有一个主题(Topic),可选标签(Tag)和额外键值对(如业务 Key),便于定位和查询。
  • Topic(主题):消息的归类,是消息的第一级类型。一个 Topic 可有多个生产者和消费者,彼此松耦合。
  • Tag(标签):子主题,是消息的第二级类型,为同一 Topic 下不同业务目的的消息提供区分。可选,便于代码管理和消息查询。
  • Group(消费组):订阅者的集合。每个消费组消费主题中一份完整消息,组内消费者竞争消费,组间互不影响。
  • Message Queue(消息队列):一个 Topic 下可有多个队列,提升并发。消费者需遍历所有队列获取全部消息。
  • Offset(消费位点):每个消费组在每个队列上的消费进度。消费一条消息,Offset 加一,便于消息重复消费和进度管理。

6. 消息消费模式

  • 集群消费(Clustering):同一消费组内的消费者分摊消费队列中的消息,实现负载均衡。
  • 广播消费(Broadcasting):同一消费组内的每个消费者都能收到全量消息,适合多副本场景。

7. RocketMQ 基本架构

在这里插入图片描述

RocketMQ 架构由四大核心组件组成:

  • Producer:生产者,负责发送消息
  • Consumer:消费者,负责消费消息
  • Broker:消息存储与转发
  • NameServer:注册中心,负责路由发现
    每个组件都支持集群部署,保证高可用和扩展性。

8. 四大核心组件介绍

  • Producer:支持同步、异步、单向三种发送方式,适应不同业务场景。

    Producer由用户进行分布式部署,消息由Producer通过多种负载均衡模式发送到Broker集群,发送低延时,支持快速失败。

    RocketMQ 提供了三种方式发送消息:同步、异步和单向

    1、同步发送:同步发送指消息发送方发出数据后会在收到接收方发回响应之后才发下一个数据包。一般用于重要通知消息,例如重要通知邮件、营销短信。

    2、异步发送:异步发送指发送方发出数据后,不等接收方发回响应,接着发送下个数据包,一般用于可能链路耗时较长而对响应时间敏感的业务场景,例如用户视频上传后通知启动转码服务。

    3、单向发送:单向发送是指只负责发送消息而不等待服务器回应且没有回调函数触发,适用于某些耗时非常短但对可靠性要求并不高的场景,例如日志收集

  • Consumer:支持 Push 和 Pull 两种消费模式,支持集群和广播消费。

消息消费者,负责消费消息,一般是后台系统负责异步消费。

1、Consumer也由用户部署,支持 PUSH 和 PULL 两种消费模式,支持集群消费和广播消费,提供实时的消息订阅机制。
2、Pull:拉取型消费者(Pull Consumer)主动从消息服务器拉取信息,只要批量拉取到消息,用户应用就会启动消费过程,	所以 Pull 称为主动消费型。
3、Push:推送型消费者(Push Consumer)封装了消息的拉取、消费进度和其他的内部维护工作,将消息到达时执行的回调接口留给用户应用程序来实现。所以 Push 称为被动消费类型,但其实从实现上看还是从消息服务器中拉取消息,不同于 Pull 的是 Push 首先要注册消费监听器,当监听器处触发后才开始消费消息。
  • Broker:负责消息存储、转发、索引、主从同步等,支持高可用部署。
    1、Broker 内部维护着一个个 Consumer Queue,用来存储消息的索引,真正存储消息的地方是 CommitLog(日志文件)。

    2、单个 Broker 与所有的 Nameserver 保持着长连接和心跳,并会定时将 Topic 信息同步到 NameServer,和 NameServer 的通信底层是通过 Netty 实现的。
    在这里插入图片描述

  • NameServer:无状态,支持横向扩展,负责 Broker 路由信息管理。

    1、每个 NameServer 结点之间是相互独立,彼此没有任何信息交互。

    2、Nameserver 被设计成几乎是无状态的,通过部署多个结点来标识自己是一个伪集群,Producer 在发送消息前从 NameServer 中获取 Topic 的路由信息也就是发往哪个 Broker,Consumer 也会定时从 NameServer 获取 Topic 的路由信息,Broker 在启动时会向 NameServer 注册,并定时进行心跳连接,且定时同步维护的 Topic 到 NameServer。

      功能主要有两个:1、和 Broker 结点保持长连接。2、维护 Topic 的路由信息。
    

9. 如何保证消息的可用性/可靠性/不丢失?

消息可能在哪些阶段丢失呢?可能会在这三个阶段发生丢失:生产阶段、存储阶段、消费阶段。
在这里插入图片描述

  • 生产阶段

    • 主要通过请求确认机制,确保消息可靠传递。
    • 同步发送时,需处理响应结果和异常。如果返回 OK,表示消息已成功发送到 Broker;如响应失败或异常,应重试。
    • 异步发送时,应在回调方法中检查发送结果,失败或异常也需重试。
    • 若发生超时,可通过查询日志 API 检查消息是否已存储成功。
  • 存储阶段

    • 可通过配置可靠性优先的 Broker 参数,避免宕机丢消息。高可靠场景建议使用同步刷盘。
    • 消息需持久化到 CommitLog(日志文件),即使 Broker 宕机,未消费的消息也能重放。
    • Broker 支持同步刷盘和异步刷盘。同步刷盘更可靠,Producer 发送消息后需等数据持久化到磁盘再返回响应。
    • Broker 主从同步复制,提升可靠性。
      在这里插入图片描述
  • 消费阶段:消费端业务处理完成后再确认消费,避免消息丢失。

Consumer 保证消息成功消费的关键在于确认的时机,不要在收到消息后就立即发送消费确认,
而是应该在执行完所有消费业务逻辑之后,再发送消费确认。
因为消息队列维护了消费的位置,逻辑执行失败了,没有确认,再去队列拉取消息,就还是之前的一条

10. 如何处理消息重复?

在这里插入图片描述

RocketMQ 保证消息至少投递一次,无法避免重复消费。需在业务端实现幂等性或去重:

  • 业务唯一标识(如订单号)+ Redis/数据库唯一索引去重
  • 乐观锁/悲观锁机制防止重复处理

11. 如何处理消息积压?

在这里插入图片描述

  • 消费者扩容:

如果当前 Topic 的 Message Queue 的数量大于消费者数量,就可以对消费者进行扩容,增加消费者,来提高消费能力,尽快把积压的消息消费玩。

  • 消息迁移 Queue 扩容:

如果当前 Topic 的 Message Queue 的数量小于或者等于消费者数量,
这种情况,再扩容消费者就没什么用,就得考虑扩容 Message Queue。
可以新建一个临时的 Topic,临时的 Topic 多设置一些 Message Queue,
然后先用一些消费者把消费的数据丢到临时的 Topic,因为不用业务处理,只是转发一下消息,还是很快的。
接下来用扩容的消费者去消费新的 Topic 里的数据,消费完了之后,恢复原状。
在这里插入图片描述

12. 顺序消息如何实现?

  • 局部顺序:同一业务 Key(如订单号)的消息通过 hash 取模发送到同一个队列,保证队列内有序。

局部顺序消息保证在某个逻辑分区或业务逻辑下的消息顺序,例如同一个订单或用户的消息按顺序消费,而不同订单或用户之间的顺序不做保证。
在这里插入图片描述

  • 全局顺序:所有消息发送到同一个队列,保证全局顺序,但吞吐量有限。

上面的主题队列数修改成 1 , 就是全局有序了 。但是会导致不能进行水平扩充,系统吞吐量受限。

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

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

相关文章

[Linux网络_71] NAT技术 | 正反代理 | 网络协议总结 | 五种IO模型

目录 1.NAT技术 NAPT 2.NAT和代理服务器 3.网线通信各层协议总结 补充说明 4.五种 IO 模型 1.什么是IO?什么是高效的IO? 2.有那些IO的方式?这么多的方式,有那些是高效的? 异步 IO 🎣 关键缺陷类比…

Unity基础学习(八)时间相关内容Time

众所周知,每一个游戏都会有自己的时间。这个时间可以是内部,从游戏开始的时间,也可以是外部真实的物理时间,时间相关内容 主要用于游戏中 参与位移计时 时间暂停等。那么我们今天就来看看Unity中和时间相关的内容。 Unity时间功能…

Java游戏服务器开发流水账(1)游戏服务器的架构浅析

新项目立项停滞,头大。近期读老项目代码看到Java,笔记记录一下。 为什么要做服务器的架构 游戏服务器架构设计具有多方面的重要意义,它直接关系到游戏的性能、可扩展性、稳定性以及用户体验等关键因素 确保游戏的流畅运行 优化数据处理&a…

计算机视觉与深度学习 | 基于Transformer的低照度图像增强技术

基于Transformer的低照度图像增强技术通过结合Transformer的全局建模能力和传统图像增强理论(如Retinex),在保留颜色信息、抑制噪声和平衡亮度方面展现出显著优势。以下是其核心原理、关键公式及典型代码实现: 一、原理分析 1. 全局依赖建模与局部特征融合 Transformer的核…

Linux 文件目录管理常用命令

pwd 显示当前绝对路径 cd 切换目录 指令备注cd -回退cd …返回上一层cd ~切换到用户主目录 ls 列出目录的内容 指令备注ls -a显示当前目录中的所有文件和目录,包括隐藏文件ls -l以长格式显示当前目录中的文件和目录ls -hl以人类可读的方式显示当前目录中的文…

【Linux 系统调试】性能分析工具perf使用与调试方法

目录 一、perf基本概念 1‌. 事件类型‌ 2‌. 低开销高精度 3‌. 工具定位‌ 二、安装与基础配置 1. 安装方法 2. 启用符号调试 三、perf工作原理 1. 数据采集机制 2. 硬件事件转化流程 四、perf应用场景 1. 系统瓶颈定位 2. 锁竞争优化 3. 缓存优化 五、perf高级…

嵌入式中屏幕的通信方式

LCD屏通信方式详解 LCD屏(液晶显示屏)的通信方式直接影响其数据传输效率、显示刷新速度及硬件设计复杂度。根据应用场景和需求,LCD屏的通信方式主要分为以下三类,每种方式在协议类型、数据速率、硬件成本及适用场景上存在显著差异…

【el-admin】el-admin关联数据字典

数据字典使用 一、新增数据字典1、新增【图书状态】和【图书类型】数据字典2、编辑字典值 二、代码生成配置1、表单设置2、关联字典3、验证关联数据字典 三、查询操作1、模糊查询2、按类别查询(下拉框) 四、数据校验 一、新增数据字典 1、新增【图书状态…

【Spring】Spring MVC笔记

文章目录 一、SpringMVC简介1、什么是MVC2、什么是SpringMVC3、SpringMVC的特点 二、HelloWorld1、开发环境2、创建maven工程a>添加web模块b>打包方式:warc>引入依赖 3、配置web.xmla>默认配置方式b>扩展配置方式 4、创建请求控制器5、创建springMVC…

如何在大型项目中解决 VsCode 语言服务器崩溃的问题

在大型C/C项目中,VS Code的语言服务器(如C/C扩展)可能因内存不足或配置不当频繁崩溃。本文结合系统资源分析与实战技巧,提供一套完整的解决方案。 一、问题根源诊断 1.1 内存瓶颈分析 通过top命令查看系统资源使用情况&#xff…

LeetCode百题刷002摩尔投票法

遇到的问题都有解决的方案,希望我的博客可以为你提供一些帮助 图片源自leetcode 题目:169. 多数元素 - 力扣(LeetCode) 一、排序法 题目要求需要找到多数值(元素个数>n/2)并返回这个值。一般会想到先…

Android Studio Gradle 中 只显示 Tasks 中没有 build 选项解决办法

一、问题描述 想把项目中某一个模块的代码单独打包成 aar ,之前是点击 AndroidStudio 右侧的 Gradle 选项,然后再点击需要打包的模块找到 build 进行打包,但是却发现没有 build 选项。 二、解决办法 1、设置中勾选 Configure all Gradle tasks… 选项 …

深入浅出之STL源码分析2_stl与标准库,编译器的关系

引言 在第一篇博客中,深入浅出之STL源码分析1_vector基本操作-CSDN博客 我们将引出下面的几个问题 1.刚才我提到了我的编译器版本是g 11.4.0,而我们要讲解的是STL(标准模板库),那么二者之间的关系是什么?…

(十二)深入了解AVFoundation-采集:人脸识别与元数据处理

(一)深入了解AVFoundation:框架概述与核心模块解析-CSDN博客 (二) 深入了解AVFoundation - 播放:AVFoundation 播放基础入门-CSDN博客 (三)深入了解AVFoundation-播放&#xff1…

Kafka 与 RabbitMQ、RocketMQ 有何不同?

一、不同的诞生背景,塑造了不同的“性格” 名称 背景与目标 产品定位 Kafka 为了解决 LinkedIn 的日志收集瓶颈,强调吞吐与持久化 更像一个“可持久化的分布式日志系统” RabbitMQ 出自金融通信协议 AMQP 的实现,强调协议标准与广泛适…

配置 Web 服务器练习

一、要求 1.通过https://ip 可以访问到网站首页 2.通过 https://ip/private/ 实现用户访问控制,仅允许已经添加的 tom,jerry 能够访问到 private 子路径的界面 3.通过 https://ip/vrit/ 实现能够访问到将系统 /nginx/virt 目录下的网页文件&#xff0…

MySQL索引详解(下)(SQL性能分析,索引使用)

索引是MySQL性能优化的核心,但如何精准分析查询瓶颈、合理设计索引,是开发者必须掌握的技能。本文结合实战案例,系统讲解SQL性能分析工具链与索引使用技巧,帮助读者构建高性能数据库系统。 一、SQL性能分析:从宏观到微…

招行数字金融挑战赛数据赛道赛题一

赛题描述:根据提供的用户行为数据,选手需要分析用户行为特征与广告内容的匹配关系,准确预测用户对测试集广告的点击情况,通过AUC计算得分。 得分0.6120,排名60。 尝试了很多模型都没有能够提升效果,好奇大…

ORB-SLAM3和VINS-MONO的对比

直接给总结,整体上orbslam3(仅考虑带imu)在初始化阶段是松耦合,localmap和全局地图优化是紧耦合。而vins mono则是全程紧耦合。然后两者最大的区别就在于vins mono其实没有对地图点进行优化,为了轻量化,它一…

安装typescript时,npm install -g typescript报错

删除C:\Users\用户\下的.npmrc文件,如果你的没有,看是不是因为将隐藏的项目勾选上了,然后去掉勾选。 重新输入