RocketMQ阅读源码前的准备

news2024/11/17 3:35:17

本文将讲解如何在IDEA中导入 RocketMQ 源码,并运行 Broker 和 NameServer,编写一个消息发送与消息消费的示例。

一. 源码导入及调试

1.1 导入源码

RocketMQ 原先是阿里巴巴集团内部的消息中间件,于2016年提交至Apache基金会孵化,并最终成为Apache顶级项目。

第一步:从GitHub上clone RocketMQ 源码:RocketMQ。点击 File->Open 导入项目。

后面关于RocketMQ的源码分析若无特殊说明,将默认使用 4.6.0 版本

第二步:构建项目

在项目根目录下执行下列命令

mvn clean install -Dmaven.test.skip=true

1.2 启动 NameServer

第一步:展开 namesrv 模块,鼠标右键选中 NamesrvStartup.java,将其拖拽到Debug As,选中 Debug ‘NamesrvStartup.java.main()’,弹出下图:

第二步:单击 Environment variables 后面的按钮,弹出配置界面,配置如下环境变量:

ROCKETMQ_HOME=E:\software-engineer\java\open-source\rocketmq-home

点击 OK->Apply 保存即可。

第三步:在刚刚指定的文件夹内创建conf、logs、store文件夹。

第四步:从 distribution 部署目录中将 broker.conflogback_broker.xmllogback_namesrv.xml 等文件复制到 conf 目录中,按需修改 broker.conf

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

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=E:\software-engineer\java\open-source\rocketmq-home\store
#CommitLog存储路径
storePatchCommitLog=E:\software-engineer\java\open-source\rocketmq-home\store\commitlog
#消费队列存储路径
storePathConsumeQueue=E:\software-engineer\java\open-source\rocketmq-home\store\consumequeue
#消息索引存储路径
storePathIndex=E:\software-engineer\java\open-source\rocketmq-home\store\index
#checkpoint 文件存储路径
storeCheckpoint=E:\software-engineer\java\open-source\rocketmq-home\store\checkpoint
#abort 文件存储路径
abortFile=E:\software-engineer\java\open-source\rocketmq-home\store\abort

第五步:点击 Debug 运行 NamesrvStartup.java,并输出“The Name Server boot success. serializeType=JSON”

1.3 启动 Broker

第一步:展开 broker 模块,启动 BrokerStartup.java ,会提示需要配置 ROCKETMQ_HOME 环境变量。与 NameServer启动时一样,配置环境变量即可:

第二步:配置-c参数,指定broker.conf 配置文件地址:

第三步:以 Debug 模式启动 BrokerStartup.java,查看${ROCKET_HOME}/logs/broker.log 文件,未报错则表示启动成功:

1.4 代码测试

1.4.1 生产者

第一步:修改org.apache.rocketmq.example.quickstart.Producer 示例程序,设置 RocketMQ NameServer地址:

public class Producer {
    public static void main(String[] args) throws MQClientException, InterruptedException {

        DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");

        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();

        for (int i = 0; i < 1; i++) {
            try {
                Message msg = new Message("TopicTest",
                    "TagA",
                    ("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) 
                );
                SendResult sendResult = producer.send(msg);
                System.out.printf("%s%n", sendResult);
            } catch (Exception e) {
                e.printStackTrace();
                Thread.sleep(1000);
            }
        }
        producer.shutdown();
    }
}

第二步:运行该方法发送消息

1.4.2 消费者

第一步:修改 org.apache.rocketmq.example.quickstart.Consumer 示例程序,设置RocketMQ NameServer地址

public class Consumer {

    public static void main(String[] args) throws InterruptedException, MQClientException {
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name_4");
        consumer.setNamesrvAddr("127.0.0.1:9876");
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
        consumer.subscribe("TopicTest", "*");
        consumer.registerMessageListener(new MessageListenerConcurrently() {

            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
                ConsumeConcurrentlyContext context) {
                System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
        consumer.start();
        System.out.printf("Consumer Started.%n");
    }
}

第二步:运行该方法,消费消息

二. RocketMQ 源码结构

RocketMQ源码组织方式基于 Maven 模块组织,RocketMQ核心目录说明如下:

  • acl:权限控制模块
  • broker:broker模块(broker启动进程)
  • client:消息客户端,包含消息生产者和消费者
  • common:公共包
  • dev:开发者信息(非源码)
  • distribution:打包分发目录(非源码)
  • example:示例代码
  • filter:消息过滤相关基础类
  • logappender:日志实现相关类
  • logging:自主实现日志相关类
  • namesrv:NameServer实现相关类(NameServer启动进程)
  • openmessaging:消息开放标准,已发布
  • remoting:远程通信模块,基于Netty
  • srvutil:服务器工具类
  • store:消息存储相关实现类
  • style:checkstyle相关实现
  • test:测试相关类
  • tools:工具类,监控命令相关实现类。

三. Rocket设计理念和设计目标

3.1 设计理念

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

  1. 首先,NameServer设计极其简单,摒弃了业界常用的使用Zookeeper充当信息管理的“注册中心”,而是自研NameServer来实现元数据的管理(Topic路由信息等)。从实际需求出发,因为Topic路由信息无须在集群之间保持强一致,追求最终一致性,并且能容忍分钟级的不一致。正是基于此种情况,RocketMQ的NameServer集群之间互不通信,极大地降低了NameServer实现的复杂程度,对网络的要求也降低了不少,但是性能相比较Zookeeper有了极大的提升。
  2. 其次是高效的IO存储机制。RocketMQ追求消息发送的高吞吐量,RocketMQ的消息存储文件设计成文件组的概念,组内单个文件大小固定,方便引入内存映射机制,所有主题的消息存储基于顺序写,极大地提供了消息写性能,同时为了兼顾消息消费与消息查找,引入了消息消费队列文件与索引文件。
  3. 最后是容忍存在设计缺陷,适当将某些工作下放给RocketMQ使用者。消息中间件的实现者经常会遇到一个难题:如何保证消息一定能被消息消费者消费,并且保证只消费一次。RocketMQ的设计者给出的解决办法是不解决这个难题,而是退而求其次,只保证消息被消费者消费,但设计上允许消息被重复消费,这样极大地简化了消息中间件的内核,使得实现消息发送高可用变得非常简单与高效,消息重复问题由消费者在消息消费时实现幂等。

3.2 设计目标

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

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

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

  3. 消息过滤 消息过滤是指在消息消费时,消息消费者可以对同一主题下的消息按照规则只消费自己感兴趣的消息。RocketMQ消息过滤支持在服务端与消费端的消息过滤机制。

    1. 消息在Broker端过滤。Broker只将消息消费者感兴趣的消息发送给消息消费者。
    2. 消息在消息消费端过滤,消息过滤方式完全由消息消费者自定义,但缺点是有很多无用的消息会从Broker传输到消费端。
  4. 消息存储 消息中间件的一个核心实现是消息的存储,对消息存储一般有如下两个维度的考量:消息堆积能力和消息存储性能。RocketMQ追求消息存储的高性能,引入内存映射机制,所有主题的消息顺序存储在同一个文件中。同时为了避免消息无限在消息存储服务器中累积,引入了消息文件过期机制与文件存储空间报警机制。

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

    1. Broker正常关机。
    2. Broker异常Crash。
    3. OS Crash。
    4. 机器断电,但是能立即恢复供电情况。
    5. 机器无法开机(可能是CPU、主板、内存等关键设备损坏)。
    6. 磁盘设备损坏。

    针对上述情况,情况14的RocketMQ在同步刷盘机制下可以确保不丢失消息,在异步刷盘模式下,会丢失少量消息。情况56属于单点故障,一旦发生,该节点上的消息全部丢失,如果开启了异步复制机制,RoketMQ能保证只丢失少量消息,RocketMQ在后续版本中将引入双写机制,以满足消息可靠性要求极高的场合。

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

  7. 确保消息必须被消费一次 RocketMQ 通过消息消费确认机制(ACK)来确保消息至少被消费一次(least once),但由于ACK消息有可能丢失等其他原因,RocketMQ无法做到消息只被消费一次,有重复消费的可能。

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

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

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

  11. 消息重试机制 消息重试是指消息在消费时,如果发送异常,消息中间件需要支持消息重新投递,RocketMQ支持消息重试机制。

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

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

相关文章

文字识别(OCR)专题——基于NCNN轻量级PaddleOCRv4模型C++推理

前言 PaddleOCR 提供了基于深度学习的文本检测、识别和方向检测等功能。其主要推荐的 PP-OCR 算法在国内外的企业开发者中得到广泛应用。在短短的几年时间里&#xff0c;PP-OCR 的累计 Star 数已经超过了32.2k&#xff0c;常常出现在 GitHub Trending 和 Paperswithcode 的日榜…

图像增强与复原、车牌检测与识别,交通最优路径搜索模型,并且基于PyQt完成GUI设计

背景&#xff1a; 综合实训教学大纲 一、实训科目设置&#xff1a; 序号 内容提要 教学 条件 一 图像增强与复原、车牌检测与识别&#xff0c;并且基于PyQt完成GUI设计 计算机、Python软件 二 交通最优路径搜索模型&#xff0c;并且基于PyQt完成GUI设计 计算机、Pytho…

VLAN间路由详细讲解

本次实验拓扑的主要概述以及设计到的相关技术 VLAN技术&#xff1a; VLAN&#xff08;Virtual Local Area Network&#xff09;即虚拟局域网&#xff0c;是将一个物理的LAN在逻辑上划分成多个广播域的通信技术。 每个VLAN是一个广播域&#xff0c;VLAN内的主机间可以直…

opencv阈值处理

阈值处理 二值化 自适应阈值 OTSU二值化

【C++】string类模拟实现过程中值得注意的点

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.有关const的使用 &#x…

【CANoe】CANoe工具使用-实现CAN通道的收、发、录、回放报文

目录 资源及目标 1. 配置工程 1.1 新建配置工程 1.2 配置两路CANoe虚拟通道 1.3配置CAN通道参数 1.3.1 配置CAN1类型&#xff08;标准CAN或者CANFD&#xff09;&#xff0c;以及波特率&#xff08;CANFD需要配置数据场和仲裁场两个段的波特率&#xff09; 1.3.2配置CAN1…

SpringBoot 集成 ChatGPT,实战附源码

1 前言 在本文中&#xff0c;我们将探索在 Spring Boot 应用程序中调用 OpenAI ChatGPT API 的过程。我们的目标是开发一个 Spring Boot 应用程序&#xff0c;能够利用 OpenAI ChatGPT API 生成对给定提示的响应。 您可能熟悉 ChatGPT 中的术语“提示”。在 ChatGPT 或类似语…

接口自动化测试思路和实战之模块化测试脚本框架

模块化测试脚本框架 需要创建独立的可描述的模块、程序片断以及待测试应用程序的脚本。这些小脚本进行组合&#xff0c;就能组成用来独立运行特定的测试的测试用例脚本。 场景一: 开发把 access_token接口地址由/cgi-bin/token 改为/cgi-bin/get_token或者修改参数等 》开发把…

原生video设置控制面板controls显示哪些控件

之前我们学习了如何使用原生video播放视频 今天来一个进阶版的——设置控制面板controls显示哪些控件 先看一下当我们使用原生video时&#xff0c;controls属性为true时&#xff0c;相关代码如下&#xff1a; 正常的控制面板默认显示的控件有&#xff1a;播放、时间线、音量调…

如何本地搭建个人hMailServer邮件服务并实现远程发送邮件

文章目录 前言1. 安装hMailServer2. 设置hMailServer3. 客户端安装添加账号4. 测试发送邮件5. 安装cpolar6. 创建公网地址7. 测试远程发送邮件8. 固定连接公网地址9. 测试固定远程地址发送邮件 前言 hMailServer 是一个邮件服务器,通过它我们可以搭建自己的邮件服务,通过cpola…

使用 mtcnn 和 facenet 进行人脸识别

一、前言 人脸识别目前有比较多的应用了&#xff0c;比如门禁系统&#xff0c;手机的人脸解锁等等&#xff0c;今天&#xff0c;我们也来实现一个简单的人脸识别。 二、思维导图 三、详细步骤 3.1 准备 3.1.1 facenet 权重文件下载 下载地址&#xff1a;https://drive.goo…

Elasticsearch:么是向量嵌入?

向量嵌入定义 向量嵌入 (vector embeddings) 是一种将单词、句子和其他数据转换为捕获其含义和关系的数字的方法。 它们将不同的数据类型表示为多维空间中的点&#xff0c;其中相似的数据点更紧密地聚集在一起。 这些数字表示可以帮助机器更有效地理解和处理这些数据。 单词和…

vue循环v-for遍历图表

循环遍历图表 index.vue主页面 <view v-if"powerPage"><view v-for"(item, index) in powerDetailsData.addMap" :key"index"><PowerEChartsCity:echartData"powerDetailsData.addMap[index]"></PowerEChartsC…

Linux Spug自动化运维平台本地部署与公网远程访问

文章目录 前言1. Docker安装Spug2 . 本地访问测试3. Linux 安装cpolar4. 配置Spug公网访问地址5. 公网远程访问Spug管理界面6. 固定Spug公网地址 前言 Spug 面向中小型企业设计的轻量级无 Agent 的自动化运维平台&#xff0c;整合了主机管理、主机批量执行、主机在线终端、文件…

mac安装elasticsearch

下载地址&#xff1a; Past Releases of Elastic Stack Software | Elastic https://www.elastic.co/cn/downloads/past-releases#elasticsearch 选择7.10版本 进入es bin目录下执行启动命令 ./elasticsearch 会报错 ./elasticsearch-env: line 126: syntax error near u…

Deckerfile

1.简介 dockerfile 是 docker 镜像构建文件。包含用于构建 docker 镜像的指令和配置。通过Dockerfile可以自动化地构建Docker镜像&#xff0c;实现快速、一致和可重复的部署。是由一条条构建镜像所需的指令和参数构成的脚本。指令按照从上到下&#xff0c;顺序执行&#xff0c…

flutter 自定义TabBar 【top 0 级别】

flutter 自定义TabBar 【top 0 级别】 前言一、基础widget二、tab 标签三、barView总结 前言 在日常开发中&#xff0c;tab 标签选项&#xff0c;是一个我们特别常用的一个组件了&#xff0c;往往我们在一个项目中&#xff0c;有很多地方会使用到它&#xff0c;每次单独去写&am…

20、Resnet 为什么这么重要

&#xff08;本文已加入“计算机视觉入门与调优”专栏&#xff0c;点击专栏查看更多文章信息&#xff09; resnet 这一网络的重要性&#xff0c;上一节大概介绍了一下&#xff0c;可以从以下两个方面来有所体现&#xff1a;第一是 resnet 广泛的作为其他神经网络的 back bone&…

L1-012:计算指数

⭐题目描述⭐ 真的没骗你&#xff0c;这道才是简单题 —— 对任意给定的不超过 10 的正整数 n&#xff0c;要求你输出 2n。不难吧&#xff1f; 输入格式&#xff1a; 输入在一行中给出一个不超过 10 的正整数 n。 输出格式&#xff1a; 在一行中按照格式 2^n 计算结果 输出 2n…

强化学习简明教程

到目前为止&#xff0c;我们主要关注监督学习问题&#xff08;主要是分类&#xff09;。 在监督学习中&#xff0c;我们得到某种由输入/输出对组成的训练数据&#xff0c;目标是能够在学习模型后根据一些新输入来预测输出。 例如&#xff0c;我们之前研究过 MNIST 的卷积神经网…