RocketMQ源码系列(一):阅读源码前的准备

1、获取RocketMQ源码

由于从GitHub上clone代码太慢,这里是从码云clone的。

1.1、源码下载:

git clone https://gitee.com/apache/rocketmq.git

IntelliJ IDEA打开源码的步骤:

Snipaste_2022-03-20_14-01-08.png

选择自己clone的源码目录,点击OK:
Snipaste_2022-03-20_14-01-08.png

源码导入成功后,如下图:

Snipaste_2022-03-20_14-01-08.png

执行Maven命令clean install,下载并编译依赖。

1.2、源码调试

如何在IntelliJ IDEA中启动NameServer、Broker,并编写一个消息发送与消息消费示例程序。

  • 启动NameServer

    展开namesrv模块,鼠标右键选中NamesrvStartup.java,选择edit 'NamesrvStartup.java.main()'按钮,如图:

Snipaste_2022-03-20_14-47-25.png

Snipaste_2022-03-20_14-47-25.png
单击Environment variables后面的按钮,弹出 Environment Variables界面,如图:、

Snipaste_2022-03-20_14-47-25.png

单击“+”,在Name输入框中输入ROCKETMQ_HOME,在 Value输入框中输入源码的保存路径(这里的路径是自己新建的一个目录,里面会放置配置文件、日志文件等,下一步会说明)。单击OK按钮,回到Debug Configuration界面。再单击OK按钮,如图:

Snipaste_2022-03-20_14-47-25.png

在RocketMQ运行主目录中(即,上一步输入的value对应的目录)创建conf、logs、store文件夹。

从RocketMQ distribution部署目录中将broker.conf、 logback_broker.xml、logback_namesrv.xml等文件复制到conf目录 中,按需修改logback_broker.xml、logback_namesrv.xml文件中日志 文件的目录,broker.conf文件目录内容如下:

brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
#nameServer地址,分号分割
namesrvAddr=127.0.0.1:9876
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
# 存储路径
storePathRootDir=D:\\SourceCode\\rocketmq\\store
#CommitLog存储路径
storePathCommitLog=D:\\SourceCode\\rocketmq\\store\\commitlog
# 消费队列存储路径
storePathConsumeQueue=D:\\SourceCode\\rocketmq\\store\\consumequeue
# 消息索引存储路径
storePathIndex=D:\\SourceCode\\rocketmq\\store\\index
#checkpoint文件存储路径
storeCheckpoint=D:\\SourceCode\\rocketmq\\store\\checkpoint
#abort文件存储路径
abortFile=D:\\SourceCode\\rocketmq\\store\\abort

在IntelliJ IDEA Debug中运行NamesrvStartup,控制台输出 The Name Server boot success. Serializetype=JSON,即启动成功。

  • 启动Broker
    类似启动NameServer步骤。

展开Broker模块,鼠标右键BrokerStartup.java。选择edit 'BrokerStartup.java.main()'按钮,在弹出的界面中选择arguments选项卡,配置-c属 性,指定broker配置文件的路径(即,参考NameServer步骤中,value对应的目录中的broker.conf的路径),如图:

Snipaste_2022-03-20_14-47-25.png

切换选项卡Environment,配置RocketMQ主目录,类似启动NameServer步骤。

以Debug模式运行BrokerStartup.java,查看 ${ROCKET_HOME}/logs/broker.log文件,未报错则表示Broker启动成功。

  • 使用RocketMQ提供的实例验证消息发送与消息消费

    修改example模块下Producer.java示例程序,设置 消息生产者的NameServer地址。如图:

Snipaste_2022-03-20_14-47-25.png

运行示例程序,查看运行结果,如果输出结果如下代码则表示消息发送成功。

Snipaste_2022-03-20_14-47-25.png

同理,修改example模块下Consumer.java示例程序,设置消息消费者的NameServer地址。

运行示例程序,查看运行结果,如果输出结果如下代码则表示消息消费成功。

Snipaste_2022-03-20_14-47-25.png

自此,说明RocketMQ调试环境已搭建成功。

1.3、RocketMQ的设计理念和设计目标

了解了RocketMQ的 设计理念和目标,这有助于我们在分析源码之前有一个清晰的思路。

1.3.1、设计理念

RocketMQ设计基于主题的发布与订阅模式,其核心功能包括消息 发送、消息存储和消息消费,整体设计追求简单和性能高效,主要体 现在如下3个方面。

  • NameServer的设计极其简单,摒弃了业界常用的将 ZooKeeper作为信息管理的“注册中心”,而是自研NameServer实现元 数据的管理(topic路由信息等)。从实际需求出发,topic路由信息 无须在集群之间保持强一致,而是追求最终一致性,并且能容忍分钟 级的不一致。正是基于这种特性,RocketMQ的NameServer集群之间互 不通信,这样极大地降低了NameServer实现的复杂度,对网络的要求 也降低了不少,性能相比较ZooKeeper还有了极大的提升。

  • 高效的I/O存储机制。RocketMQ追求消息发送的高吞吐量, RocketMQ的消息存储文件被设计成文件组的概念,组内单个文件大小 固定,方便引入内存映射机制,所有主题的消息存储按顺序编写,极 大地提升了消息的写性能。同时为了兼顾消息消费与消息查找,引入了消息消费队列文件与索引文件。

  • 容忍存在设计缺陷,适当将某些工作下放给RocketMQ使用者。消息中间件的实现者经常会遇到一个难题:如何保证消息一定能 被消息消费者消费,并且只消费一次?

RocketMQ的设计者给出的解决办法是不解决这个难题,而是退而 求其次,只保证消息被消费者消费,在设计上允许消息被重复消费。 这样极大地简化了消息中间件的内核,使得实现消息发送高可用变得 非常简单和高效,消息重复问题由消费者在消息消费时实现幂等。

1.3.2、设计目标

作为一款消息中间件,RocketMQ需要解决如下问题。

  • 架构模式 RocketMQ与大部分消息中间件一样,采用发布订阅模式,主要参 与组件包括:消息发送者、消息服务器(消息存储)、消息消费和路 由发现。

  • 顺序消息 所谓顺序消息,就是消息消费者按照消息达到消息存储服务器的 顺序消费。RocketMQ可以严格保证消息有序。

  • 消息过滤 消息过滤是指在消息消费时,消息消费者可以对同一主题下的消 息按照规则只消费自己感兴趣的消息。RocketMQ消息过滤是由服务端 和消费端共同完成的。

  • 消息存储 消息中间件的一个核心实现是消息的存储,对于消息存储一般有 如下两个维度的考量:消息堆积能力和消息存储性能。RocketMQ追求 消息存储的高性能,引入内存映射机制,所有主题的消息按顺序存储 在同一个文件中。同时为了避免消息在消息存储服务器中无限地累 积,引入了消息文件过期机制与文件存储空间报警机制。

  • 消息高可用性 通常影响消息可靠性的有以下几种情况。

    1)Broker异常崩溃。

    2)操作系统崩溃。

    3)机器断电,但是能立即恢复供电。

    4)机器无法开机(可能是CPU、主板、内存等关键设备损坏)。

    5)磁盘设备损坏。

    对于前3种情况,RocketMQ在同步刷盘模式下可以确保不丢失消息,在异步刷盘模式下,会丢失少量消息。后2种情况属于单点故障, 一旦发生,该节点上的消息会全部丢失。如果开启了异步复制机制, RoketMQ能保证只丢失少量消息。

  • 消息到达(消费)低延迟 RocketMQ在消息不发生堆积时,以长轮询模式实现准实时的消息 推送模式。

  • 确保消息必须被消费一次 RocketMQ通过消息消费确认机制(ACK)确保消息至少被消费一 次,因为ACK消息有可能出现丢失等情况,RocketMQ无法做到消息只被 消费一次,所以有重复消费的可能。

  • 回溯消息 回溯消息是指消息消费端已经消费成功,根据业务要求,需要重 新消费消息。RocketMQ支持按时间向前或向后回溯消息,时间维度可 精确到毫秒。

  • 消息堆积 消息中间件的主要功能是异步解耦,必须能应对前端的数据洪 峰,提高后端系统的可用性,这必然要求消息中间件具备一定的消息 堆积能力。RocketMQ使用磁盘文件存储消息(内存映射机制),并且 在物理布局上为多个大小相等的文件组成逻辑文件组,可以无限循环 使用。RocketMQ消息存储文件并不是永久存储在消息服务器端的,而 是提供了过期机制,默认保留3天。

  • 定时消息 定时消息是指消息发送到Broker后,不能被消息消费端立即消 费,而是要到特定的时间点或者等待特定的时间后才能被消费。因为 如果要支持任意精度的定时消息消费,就必须在消息服务端对消息进 行排序,这势必带来很大的性能损耗,所以RocketMQ不支持任意进度 的定时消息,只支持特定延迟级别。

  • 消息重试机制 RocketMQ支持消息重试机制。消息重试是指在消息消费时如果发 生异常,消息中间件支持消息重新投递。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值