RocketMQ高性能核心原理与源码架构剖析

文章目录

  • 1、源码环境搭建
    • 1.1、主要功能模块
    • 1.2、源码启动服务
      • 1.2.1、 启动nameServer
      • 1.2.2、 启动Broker
      • 1.2.3、 发送消息
      • 1.2.4、 消费消息
  • 2、源码剖析
    • 2.1、NameServer的启动过程
    • 2.2、Broker服务启动过程
    • 2.3、Netty服务注册框架
      • 2.3.1、关注重点
      • 2.3.2、源码重点

1、源码环境搭建

1.1、主要功能模块

​ RocketMQ的官方Git仓库地址:https://github.com/apache/rocketmq 可以用git把项目clone下来或者直接下载代码包。
​ 也可以到RocketMQ的官方网站上下载指定版本的源码: http://rocketmq.apache.org/dowloading/releases/
源码下很多的功能模块,很容易让人迷失方向,我们只关注下几个最为重要的模块:

  • broker: Broker 模块(broke 启动进程)
  • client :消息客户端,包含消息生产者、消息消费者相关类
  • example: RocketMQ 例代码
  • namesrv:NameServer模块
  • store:消息存储模块
  • remoting:远程访问模块

1.2、源码启动服务

​ 将源码导入IDEA后,需要先对源码进行编译。编译指令 clean install -Dmaven.test.skip=true
编译完成后就可以开始调试代码了。调试时需要按照以下步骤:
​ 调试时,先在项目目录下创建一个conf目录,并从distribution拷贝broker.conf和logback_broker.xml和logback_namesrv.xml
在这里插入图片描述

1.2.1、 启动nameServer

​ 展开namesrv模块,运行NamesrvStartup类即可启动NameServer

image.png

启动时,会报错,提示需要配置一个ROCKETMQ_HOME环境变量。
在这里插入图片描述
这个环境变量我们可以在机器上配置,跟配置JAVA_HOME环境变量一样。也可以在IDEA的运行环境中配置。目录指向源码目录即可。
在这里插入图片描述

配置完成后,再次执行,看到以下日志内容,表示NameServer启动成功

The Name Server boot success. serializeType=JSON

1.2.2、 启动Broker

启动Broker之前,我们需要先修改之前复制的broker.conf文件

brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH# 自动创建Topic
autoCreateTopicEnable=true
# nameServ地址
namesrvAddr=127.0.0.1:9876
# 存储路径
storePathRootDir=E:\\RocketMQ\\data\\rocketmq\\dataDir
# commitLog路径
storePathCommitLog=E:\\RocketMQ\\data\\rocketmq\\dataDir\\commitlog
# 消息队列存储路径
storePathConsumeQueue=E:\\RocketMQ\\data\\rocketmq\\dataDir\\consumequeue
# 消息索引存储路径
storePathIndex=E:\\RocketMQ\\data\\rocketmq\\dataDir\\index
# checkpoint文件路径
storeCheckpoint=E:\\RocketMQ\\data\\rocketmq\\dataDir\\checkpoint
# abort文件存储路径
abortFile=E:\\RocketMQ\\data\\rocketmq\\dataDir\\abort

然后Broker的启动类是broker模块下的BrokerStartup。

启动Broker时,同样需要ROCETMQ_HOME环境变量,并且还需要配置一个-c 参数,指向broker.conf配置文件。
image.png

然后重新启动,即可启动Broker。

1.2.3、 发送消息

启动example模块下的org.apache.rocketmq.example.quickstart.Producer类即可发送消息。

但是在测试源码中,需要指定NameServer地址。这个NameServer地址有两种指定方式,一种是配置一个NAMESRV_ADDR的环境变量。另一种是在源码中指定。我们可以在源码中加一行代码指定NameServer

producer.setNamesrvAddr("127.0.0.1:9876");

然后就可以发送消息了。

1.2.4、 消费消息

可以使用同一模块下的org.apache.rocketmq.example.quickstart.Consumer类来消费消息。运行时同样需要指定NameServer地址

consumer.setNamesrvAddr("192.168.232.128:9876");

这样整个调试环境就搭建好了。

2、源码剖析

2.1、NameServer的启动过程

关注重点
​ 在RocketMQ集群中,实际记性消息存储、推送等核心功能点额是Broker。而NameServer的作用,其实和微服务中的注册中心非常类似,他只是提供了Broker端的服务注册与发现功能。
源码重点
​ NameServer的启动入口类是org.apache.rocketmq.namesrv.NamesrvStartup。其中的核心是构建并启动一个NamesrvController。这个Cotroller对象就跟MVC中的Controller是很类似的,都是响应客户端的请求。只不过,他响应的是基于Netty的客户端请求。

​ 另外,他的实际启动过程,其实可以配合NameServer的启动脚本进行更深入的理解。

​ 从NameServer启动和关闭这两个关键步骤,我们可以总结出NameServer的组件其实并不是很多,整个NameServer的结构是这样的;
在这里插入图片描述
从这里也能看出, RocketMQ的整体源码风格就是典型的MVC思想。Controller响应请求,Service处理业务,各种Table保存消息。

2.2、Broker服务启动过程

关注重点

​ Broker是整个RocketMQ的业务核心。所有消息存储、转发这些重要的业务都是Broker进行处理。

​ 这里重点梳理Broker有哪些内部服务。这些内部服务将是整理Broker核心业务流程的起点。

源码重点

Broker启动的入口在BrokerStartup这个类,可以从他的main方法开始调试。

启动过程关键点:重点也是围绕一个BrokerController对象,先创建,然后再启动。

首先: 在BrokerStartup.createBrokerController方法中可以看到Broker的几个核心配置:

  • BrokerConfig : Broker服务配置
  • MessageStoreConfig : 消息存储配置。 这两个配置参数都可以在broker.conf文件中进行配置
  • NettyServerConfig :Netty服务端占用了10911端口。同样也可以在配置文件中覆盖。
  • NettyClientConfig : Broker既要作为Netty服务端,向客户端提供核心业务能力,又要作为Netty客户端,向NameServer注册心跳。

这些配置是我们了解如何优化 RocketMQ 使用的关键。

然后: 在BrokerController.start方法可以看到启动了一大堆Broker的核心服务,我们挑一些重要的

this.messageStore.start();//启动核心的消息存储组件this.remotingServer.start();
this.fastRemotingServer.start(); //启动两个Netty服务this.brokerOuterAPI.start();//启动客户端,往外发请求BrokerController.this.registerBrokerAll: //向NameServer注册心跳。this.brokerStatsManager.start();
this.brokerFastFailure.start();//这也是一些负责具体业务的功能组件

我们现在不需要了解这些核心组件的具体功能,只要有个大概,Broker中有一大堆的功能组件负责具体的业务。后面等到分析具体业务时再去深入每个服务的细节。

我们需要抽象出Broker的一个整体结构:
在这里插入图片描述

可以看到Broker启动了两个Netty服务,他们的功能基本差不多。实际上,在应用中,可以通过producer.setSendMessageWithVIPChannel(true),让少量比较重要的producer走VIP的通道。而在消费者端,也可以通过consumer.setVipChannelEnabled(true),让消费者支持VIP通道的数据。

2.3、Netty服务注册框架

2.3.1、关注重点

​ 网络通信服务是构建分布式应用的基础,也是我们去理解RocketMQ底层业务的基础。这里就重点梳理RocketMQ的这个服务注册框架,理解各个业务进程之间是如何进行RPC远程通信的。

​ Netty的所有远程通信功能都由remoting模块实现。RemotingServer模块里包含了RPC的服务端RemotingServer以及客户端RemotingClient。在RocketMQ中,涉及到的远程服务非常多,在RocketMQ中,NameServer主要是RPC的服务端RemotingServer,Broker对于客户端来说,是RPC的服务端RemotingServer,而对于NameServer来说,又是RPC的客户端。各种Client是RPC的客户端RemotingClient。

​ 需要理解的是,RocketMQ基于Netty保持客户端与服务端的长连接Channel。只要Channel是稳定的,那么即可以从客户端发请求到服务端,同样服务端也可以发请求到客户端。例如在事务消息场景中,就需要Broker多次主动向Producer发送请求确认事务的状态。所以,RemotingServer和RemotingClient都需要注册自己的服务。

2.3.2、源码重点

​ 1、哪些组件需要Netty服务端?哪些组件需要Netty客户端? 比较好理解的,NameServer需要NettyServer。客户端,Producer和Consuer,需要NettyClient。Broker需要NettyServer响应客户端请求,需要NettyClient向NameServer注册心跳。但是有个问题, 事务消息的Producer也需要响应Broker的事务状态回查,他需要NettyServer吗?

NameServer不需要NettyClient,这也验证了之前介绍的NameServer之间不需要进行数据同步的说法。

​ 2、所有的RPC请求数据都封账成RemotingCommand对象。而每个处理消息的服务逻辑,都会封装成一个NettyRequestProcessor对象。

​ 3、服务端和客户端都维护一个processorTable,这是个HashMap。key是服务码requestCode,value是对应的运行单元 Pair<NettyRequestProcessor,ExecutorService>类型,包含了处理Processor和执行线程的线程池。具体的Processor,由业务系统自行注册。Broker服务注册见,BrokerController.registerProcessor(),客户端的服务注册见MQClientAPIImpl。NameServer则会注册一个大的DefaultRequestProcessor,统一处理所有服务。

​ 4、请求类型分为REQUEST和RESPONSE。这是为了支持异步的RPC调用。NettyServer处理完请求后,可以先缓存到responseTable中,等NettyClient下次来获取,这样就不用阻塞Channel了,可以提升请求吞吐量。猜一猜Producer的同步请求的流程是什么样的?

​ 5、重点理解remoting包中是如何实现全流程异步化。

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

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

相关文章

AJAX学习

文章目录 创建 XMLHttpRequest 对象向服务器发送请求XMLHttpRequest.open()XMLHttpRequest.send()GET或POST 服务器响应XMLHttpRequest 的属性XMLHttpRequest.readyStateXMLHttpRequest.onreadystatechangeXMLHttpRequest.responseXMLHttpRequest.responseTypeXMLHttpRequest.r…

OpenAI官方吴达恩《ChatGPT Prompt Engineering 提示词工程师》(7)聊天机器人 / ChatBot

聊天机器人 / ChatBot 使用大型语言模型来构建你的自定义聊天机器人 在本视频中&#xff0c;你将学习使用OpenAI ChatCompletions格式的组件构建一个机器人。 环境准备 首先&#xff0c;我们将像往常一样设置OpenAI Python包。 import os import openai from dotenv import…

ruoyi框架修改左侧菜单样式

菜单效果 ruoyi前端框架左侧的菜单很丑&#xff0c;我们需要修改一下样式&#xff0c;下面直接看效果。 修改代码 1、sidebar.scss .el-menu-item, .el-submenu__title {overflow: hidden !important;text-overflow: ellipsis !important;white-space: nowrap !important;//…

vue3——pixi初学,编写一个简单的小游戏,复制粘贴可用学习

pixi官网 小游戏效果 两个文件夹 一个index.html 一个data.js //data.js import { reactive } from "vue"; import { Sprite, utils, Rectangle, Application, Text, Graphics } from "pixi.js";//首先 先创建一个舞台 export const app new Applicat…

QT配置MySQL数据库 ninja: build stopped: subcommand failed

QT配置MySQL数据库 我当前的软件版本&#xff1a;QT Creator 10.0.2 (community)&#xff0c;MingW 6.4.3 (QT6)&#xff0c;MySQL 8.0。 MySQL不配置支持的数据库有QList("QSQLITE", "QODBC", "QPSQL")&#xff0c;这个时候是不支持MYSQL数据…

[极客大挑战 2019]RCE ME 取反绕过正则匹配 绕过disable_function设置

目录 取反 1.蚁剑插件绕过 2.baypass disable_function open_dir/disable_function putenv()/LD_PRELOAD 来绕过限制 利用条件 利用思路 有意思。。。。 <?php error_reporting(0); if(isset($_GET[code])){$code$_GET[code];if(strlen($code)>40){die("Th…

windbg -I之后如何恢复原有的

直接运行了一下windbg -I&#xff0c;抓取了注册表行为&#xff0c;然后这里记录一下&#xff0c;方便翻阅。 抓取到的windbg的注册表 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger 将值改为 "C:\WINDOWS\system32\vsji…

git 本地工作区和仓库区基本使用

(1)git 本地有三个区 工作区和暂存区和 git管理的仓库. &#xff08;自行动手实践理解,然后就入门了&#xff09;(2)本地初次使用git做的事情,需要做如下工作 git config --global user.name "xx" git config --global user.email xxxqq.com git config --globa…

java 工程管理系统源码+项目说明+功能描述+前后端分离 + 二次开发

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

编写第一个Go程序

编写第一个Go程序 1. 开发环境构建 在Go语言中&#xff0c;开发环境的构建需要设置GOPATH环境变量。在1.8版本之前&#xff0c;必须显式设置GOPATH环境变量。而在1.8版本及之后&#xff0c;如果没有设置GOPATH&#xff0c;Go将使用默认值。 在Unix系统上&#xff0c;默认值为…

基于YOLOv8模型的条形码二维码检测系统(PyTorch+Pyside6+YOLOv8模型)

摘要&#xff1a;基于YOLOv8模型的条形码二维码检测系统可用于日常生活中检测与定位条形码与二维码目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的目标检测&#xff0c;另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标检测…

Android12之仿Codec2.0实现传递编解码器组件本质(四十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

多策略改进蜣螂优化--螺旋搜索+最优值引导+反向学习策略

声明&#xff1a;对于作者的原创代码&#xff0c;禁止转售倒卖&#xff0c;违者必究&#xff01; 关于蜣螂算法的原理网上有很多&#xff0c;本文就不再详细介绍&#xff0c;本期算法是作者在参考了网上一些文献后自行改进的&#xff0c;接下来直接上改进策略&#xff1a; ①螺…

十六)Stable Diffusion教程:出图流程化

今天说一个流程化出图的案例&#xff0c;适用很多方面。 1、得到线稿&#xff0c;自己画或者图生图加线稿lora出线稿&#xff1b;如果想sd出图调整参数不那么频繁细致&#xff0c;则线稿的素描关系、层次、精深要表现出来&#xff0c;表现清楚。 2、文生图&#xff0c;seed随机…

前后端分离毕设项目之springboot同城上门喂遛宠物系统(内含文档+源码+教程)

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

Quartz 建表语句SQL文件

SQL文件在jar里面&#xff0c;github下载 https://github.com/quartz-scheduler/quartz/releases/tag/v2.3.2 解压&#xff0c;sql文件路径&#xff1a;quartz-core\src\main\resources\org\quartz\impl\jdbcjobstore tables_mysql_innodb.sql # # In your Quartz propertie…

七天学会C语言-第七天(结构体)

1.定义结构体 例 1&#xff1a;把一个学生的信息(包括学号、姓名、性别、住址等 4 项信息) 放在一个结构体变量中&#xff0c;然后输出这个学生的信息。 #include <stdio.h>struct Student {int student_id;char name[30];char gender;char address[60]; };int main() …

Flink的部署模式:Local模式、Standalone模式、Flink On Yarn模式

Flink常见的部署模式 Flink部署、执行模式Flink的部署模式Flink的执行模式 Local本地模式下载安装启动、停止Flink提交测试任务停止作业 Standalone独立模式会话模式单作业模式应用模式 YARN运行模式会话模式启动Hadoop集群申请一个YARN会话查看Yarn、Flink提交作业查看、测试作…

SQL模板-用户留存率计算

在这段实习中&#xff0c;我遇到了用户留存率计算的需求&#xff0c;这里做个总结。 首先来讲下&#xff0c;什么是用户留存&#xff1f; 在互联网行业中&#xff0c;用户在某段时间内开始使用应用&#xff0c;经过一段时间后&#xff0c;仍然继续使用该应用的用户。用户留存一…

5.docker可视化工具(Portainer)

本文操作&#xff0c;在 192.168.204.102 机器执行 安装最新版 portainer&#xff0c;请使用 portainer/portainer-ce 镜像。图片来源&#xff1a;https://hub.docker.com/r/portainer/portainer。   来这里可查看最新版本&#xff1a;https://github.com/portainer/p…