1、RocketMQ 核心架构拆解

news2025/5/12 21:16:07

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.coloradmin.cn/o/2374204.html

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

相关文章

vue3 element-plus 输入框回车跳转页面问题处理

问题描述&#xff1a; 当页面搜索条件只有一个的情况下&#xff0c;输入框不管有没有值&#xff0c;回车后会跳转页面 解决办法&#xff0c;给表单添加 submit.prevent <el-form ref"ruleForm" :model"search" label-width"120px" class&qu…

快速入门深度学习系列(2)----损失函数、逻辑回归、向量化

针对深度学习入门新手目标不明确 知识体系杂乱的问题 拟开启快速入门深度学习系列文章的创作 旨在帮助大家快速的入门深度学习 写在前面&#xff1a; 本系列按照吴恩达系列课程顺序发布(说明一下为什么不直接看原笔记 因为内容太多 没有大量时间去阅读 所有作者需要一次梳理…

[超详细,推荐!!!]前端性能优化策略详解

学习记录&#xff0c;部分内容版权归妙码学院 1.优化内容包括那些 其实前端的优化&#xff0c;整体粗略概括下来&#xff0c;白话之&#xff1a; 打开速度怎么变快再次打开速度怎么变快操作怎么才顺滑动画怎么保证流畅 2.性能优化 2.1首屏加载优化 在了解优化方法和策略之…

数据提取之BeautifulSoup4快速使用

文章目录 一、前言二、概述2.1 安装2.2 初始化2.3 对象类型 三、遍历文档树3.1 子节点3.2 父节点3.3 兄弟节点3.4 前后节点3.5 节点内容3.5.1 文本内容3.5.2 属性值3.5.3 标签删除 四、搜索文档树4.1 find_all4.2 find4.3 CSS选择器4.4 更多 一、前言 官方文档&#xff1a;http…

list类的详细讲解

【本节目标】 1. list的介绍及使用 2. list的深度剖析及模拟实现 3. list与vector的对比 1. list的介绍及使用 1.1 list的介绍 1. list 是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2. list 的底层是双向链表结构&a…

Linux系统下安装mongodb

1. 配置MongoDB的yum仓库 创建仓库文件 sudo vi /etc/yum.repos.d/mongodb-org.repo添加仓库配置 根据系统版本选择配置&#xff08;以下示例为CentOS 7和CentOS 9的配置&#xff09;&#xff1a; CentOS 7&#xff08;安装MongoDB 5.0/4.2等旧版本&#xff09;&#xff1a; In…

kuka, fanuc, abb机器人和移动相机的标定

基础知识 : 一, 9点标定之固定相机标定: 图1: 固定位置相机拍照 因为相机和机器人的基坐标系是固定的, 所以在海康威视相机的9点标定功能栏中, 填上海康使用“圆查找”捕捉到的坐标值, 再将机器人显示的工具坐标系在基坐标系的实时位置pos_act值填入物理坐标X, Y中即可 图2:…

Android Framework学习四:init进程实现

文章目录 init流程简介init源码执行顺序执行顺序 init进程的具体工作事项挂载文件系统设置 SELinuxSecondStageMaininit.rc启动zygote和serviceManager进程的重要性serviceManager工作原理 Framework学习之系列文章 init流程简介 下面图片主要围绕 Android 系统中init进程的运…

Java引用RabbitMQ快速入门

这里写目录 Java发送消息给MQ消费者接收消息实现一个队列绑定多个消费者消息推送限制 Fanout交换机路由的作用Direct交换机使用案例 Topic交换机声明队列和交换机的方式MQ消息转换器业务改造生产者可靠性设置重连 系统可靠性 Java发送消息给MQ public void testSendMessage() t…

用R语言+随机森林玩转遥感空间预测-基于R语言机器学习遥感数据处理与模型空间预测技术及实际项目案例分析

遥感数据具有高维度、非线性及空间异质性等特点&#xff0c;传统分析方法往往难以充分挖掘其信息价值。机器学习技术的引入为遥感数据处理与模型预测提供了新的解决方案&#xff0c;其中随机森林&#xff08;Random Forest&#xff09;以其优异的性能和灵活性成为研究者的首选工…

Spring Boot 文件上传实现详解

在项目开发过程中&#xff0c;文件上传是极为常见的功能需求。对于熟悉 Spring MVC 文件上传操作的开发者而言&#xff0c;Spring Boot 中的文件上传与之原理基本相通&#xff0c;只是在依赖管理和配置方式上更为简化。接下来&#xff0c;将详细阐述 Spring Boot 项目中文件上传…

查看单元测试覆盖率

文章目录 1、POM文件配置2、编写单元测试3、执行单元测试4、查看单元测试覆盖率 1、POM文件配置 pom文件配置jacoco插件 <!-- 生成JaCoCo覆盖率数据插件 --> <plugin><groupId>org.jacoco</groupId><artifactId>jacoco-maven-plugin</artif…

基于SpringBoot的在线教育管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

C# 方法(方法重载)

本章内容: 方法的结构 方法体内部的代码执行 局部变量 局部常量 控制流 方法调用 返回值 返回语句和void方法 局部函数 参数 值参数 引用参数 引用类型作为值参数和引用参数 输出参数 参数数组 参数类型总结 方法重载 命名参数 可选参数 栈帧 递归 方法重载 一个类中可以有多个…

3、食品包装控制系统 - /自动化与控制组件/food-packaging-control

76个工业组件库示例汇总 食品包装线控制系统 这是一个用于食品包装线控制系统的自定义组件&#xff0c;提供了食品包装生产线的可视化监控与控制界面。组件采用工业风格设计&#xff0c;包含生产流程控制、实时数据监控和逻辑编程三个主要功能区域。 功能特点 工业风格UI设…

初始图形学(7)

上一章完成了相机类的实现&#xff0c;对之前所学的内容进行了封装与整理&#xff0c;现在要学习新的内容。 抗锯齿 我们放大之前渲染的图片&#xff0c;往往会发现我们渲染的图像边缘有尖锐的"阶梯"性质。这种阶梯状被称为"锯齿"。当真实的相机拍照时&a…

线程的一些事(2)

在java中&#xff0c;线程的终止&#xff0c;是一种“软性”操作&#xff0c;必须要对应的线程配合&#xff0c;才能把终止落实下去 然而&#xff0c;系统原生的api其实还提供了&#xff0c;强制终止线程的操作&#xff0c;无论线程执行到哪&#xff0c;都能强行把这个线程干掉…

使用lldb看看Rust的HashMap

目录 前言 正文 读取桶的状态 获取键值对 键值对的指针地址 此时&#xff0c;读取数据 读取索引4的键值对 多添加几个键值对 使用i32作为键&#xff0c;&str作为值 使用i32作为键&#xff0c;String作为值 前言 前面使用ldb看了看不同的类型&#xff0c;这篇再使用…

2025最新免费视频号下载工具!支持Win/Mac,一键解析原画质+封面

软件介绍 适用于Windows 2025 最新5月蝴蝶视频号下载工具&#xff0c;免费使用&#xff0c;无广告且免费&#xff0c;支持对原视频和封面进行解析下载&#xff0c;亲测可用&#xff0c;现在很多工具都失效了&#xff0c;难得的几款下载视频号工具&#xff0c;大家且用且珍…

Newton GPU 机器人仿真器入门教程(零)— NVIDIA、DeepMind、Disney 联合推出

系列文章目录 目录 系列文章目录 前言 一、快速入门 1.1 实时渲染 1.2 USD 渲染 1.3 示例&#xff1a;创建一个粒子链 二、重要概念 三、API 参考 3.1 求解器 3.1.1 XPBD 求解器 3.1.2 VBD 求解器 3.1.3 MuJoCo 求解器 3.2 关节控制模式 四、Newton 集成 4.1 Is…