RocketMQ -- 低时延、高性能、高可靠、万亿级容量、灵活扩展的分布式消息流式传输平台

第一章 RocketMQ 概述

一、RocketMQ 简介

1.1 消息队列

MQ(Message Queue)是一种提供消息队列服务的中间件,也称消息中间件,是一套提供了海量消息生产、存储、消费全过程 API 的软件系统。

MQ 的作用:

  1. 限流削峰
  2. 异步解耦
  3. 数据收集

常见的 MQ:

MQ 开发语言 单机吞吐量

Topic

社区活跃度
ActiveMQ Java 语言 万级 -
RabbitMQ ErLang 语言 万级 -
Kafka Scala/Java 语言 十万级 百级 Topic 会影响吞吐量
RocketMQ Java 语言 十万级 千级 Topic 会影响吞吐量

MQ 协议:

协议 描述
JMS

JMS(Java Message Service),是 Java 平台上有关 MOM(Message Oriented Middleware 面向消息的中间件) 的技术规范,它便于消息系统中的 Java 应用程序进行消息交换,并且通过提供标准的产生、发送、接受消息的接口,简化企业应用的开发。

ActiveMQ 是该协议的典型实现。

STOMP

STOMP(Streaming Text Orientated Message Protocol),是一种 MOM 的简单文本协议。STOMP 提供一个可互操作式的连接格式,允许客户端与任意 STOMP 消息代理进行交互。

ActiveMQ 是该协议的典型实现,RabbitMQ 通过插件可以支持该协议。

AMQP

AMQP(Advanced Message Queuing Protocol),是一个提供统一消息服务的应用层标准,是应用层协议的一个开放标准,是一种 MOM 设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品、不同开发语言等条件的现在。

RabbitMQ是该协议的典型实现。

MQTT

MQTT(Message Queuing Telemetry Transport),是 IBM 开发的一个即时通讯协议,是一种二进制协议,主要用于服务器和低功耗 loT 设备间的通信。该协议支持所有平台,几乎可以把所有物联网物品和外部链接起来,被用来做传感器和制动器的通信协议。

RabbitMq 通过插件可以支持该协议。

1.2 RocketMQ 简介

Apache RocketMQ 是一款由阿里巴巴提供的开源的分布式消息中间件,是一个分布式消息和流式处理平台,具有低时延、高性能和高可靠性、万亿级容量和灵活扩展的特点,适用于构建海量消息堆积和异步解耦功能的应用系统。

Apache RocketMQ 自诞生以来,因其架构简单、业务功能丰富、具备极强可扩展性等特点被众多企业开发者以及云厂商广泛采用。历经十余年的大规模场景打磨,RocketMQ 已经成为业内共识的金融级可靠业务消息首选方案,被广泛应用于互联网、大数据、移动互联网、物联网等领域的业务场景。

1.3 RocketMQ 基本概念

主题(Topic):

主题是  RocketMQ 中消息传输和存储的顶层容器,用于标识同一类业务逻辑的消息。主题通过 TopicName 来做唯一标识和区分。

消息(Message):

消息是指消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题。 生产者将业务数据的负载和拓展属性包装成消息发送到服务端,服务端按照相关语义将消息投递到消费端进行消费。

消息类型(MessageType):

RocketMQ 中按照消息传输特性的不同而定义的分类,用于类型管理和安全校验。RocketMQ 支持的消息类 型有普通消息、顺序消息、事务消息和定时/延时消息。

RocketMQ 从5.0版本开始,支持强制校验消息类型,即每个主题 Topic 只允许发送一种消息类型的消息, 这样可以更好的运维和管理生产系统,避免混乱。但同时保证向下兼容4.x版本行为,强制校验功能默认开启。

消息队列(MessageQueue):

消息队列是 RocketMQ 中消息存储和传输的实际容器,也是消息的最小存储单元。RocketMQ 的所有主 题都是由多个队列组成,以此实现队列数量的水平拆分和队列内部的流式存储。队列通过 QueueId 来做唯一标识和区分。

消息视图(MessageView):

消息视图是  Apache RocketMQ 面向开发视角提供的一种消息只读接口。通过消息视图可以读取消息内部的多个属性和负载信息,但是不能对消息本身做任何修改。

消息标签(MessageTag):

消息标签 是 RocketMQ 提供的细粒度消息分类属性,可以在主题层级之下做消息类型的细分,消费者通过订阅特定的标签来实现细粒度过滤。

消息位点(MessageQueueOffset):

消息是按到 达 RocketMQ 服务端的先后顺序存储在指定主题的多个队列中,每条消息在队列中都有一个唯一的 Long 类型坐标,这个坐标被定义为消息位点。

消费位点(ConsumerOffset):

一条消息被 某个消费者消费完成后不会立即从队列中删除,RocketMQ 会基于每个消费者分组记录消费过的最新一条消息的位点,即消费位点。

消息索引(MessageKey):

消息索引 是 RocketMQ 提供的面向消息的索引属性,通过设置的消息索引可以快速查找到对应的消息内容。

生产者(Producer):

生产者 是 RocketMQ 系统中用来构建并传输消息到服务端的运行实体。生产者通常被集成在业务系统中,将业务消息按照要求封装成消息并发送至服务端。

事务检查器(TransactionChecker):

事务 检查器 RocketMQ 中生产者用来执行本地事务检查和异常事务恢复的监听器,事务检查器应该通过业务侧数据的状态来检查和判断事务消息的状态。

事务状态(TransactionResolution)

Rock etMQ 中事务消息发送过程中,事务提交的状态标识,服务端通过事务状态控制事务消息是否应该提交和投递。事务状态包括事务提交、事务回滚和事务未决。

消费者(Consumer):

消 费者是 RocketMQ 中用来接收并处理消息的运行实体。消费者通常被集成在业务系统中,从服务端获取消息,并将消息转化成业务可理解的信息,供业务逻辑处理。

消费者分组(ConsumerGroup):

消 费者分组是 RocketMQ 系统中承载多个消费行为一致的消费者的负载均衡分组。和消费者不同,消费者分组并不是运行实体,而是一个逻辑资源。在 RocketMQ 中,通过消费者分组内初始化多个消费者实现消费性能的水平扩展以及高可用容灾。

 消费结果(ConsumeResult):

RocketMQ 中 PushConsumer 消费监听器处理消息完成后返回的处理结果,用来标识本次消息是否正确处理。消费结果包含消费成功和消费失败。

订阅关系(Subscription):

订阅关系是Apache RocketMQ 系统中消费者获取消息、处理消息的规则和状态配置。订阅关系由消费者分组动态注册到服务端系统,并在后续的消息传输中按照订阅关系定义的过滤规则进行消息匹配和消费进度维护。

消息过滤:

消费者可以通过订阅指定消息标签(Tag)对消息进行过滤,确保最终只接收被过滤后的消息合集。过滤规则的计算和匹配在 RocketMQ 的服务端完成。

重置消费位点:

以时间轴为坐标,在消息持久化存储的时间范围内,重新设置消费者分组对已订阅主题的消费进度,设置完成后消费者将接收设定时间点之后,由生产者发送到 RocketMQ 服务端的消息。

消息轨迹:

在一条消息从生产者发出到消费者接收并处理过程中,由各个相关节点的时间、地点等数据汇聚而成的完整链路信息。通过消息轨迹,您能清晰定位消息从生产者发出,经由 RocketMQ 服务端,投递给消费者的完整链路,方便定位排查问题。

消息堆积:

生产者已经将消息发送到 RocketMQ 的服务端,但由于消费者的消费能力有限,未能在短时间内将所有消息正确消费掉,此时在服务端保存着未被消费的消息,该状态即消息堆积。

事务消息:

事务消息是 RocketMQ 提供的一种高级消息类型,支持在分布式场景下保障消息生产和本地事务的最终一致性。

定时/延时消息:

定时/延时消息是 RocketMQ 提供的一种高级消息类型,消息被发送至服务端后,在指定时间后才能被消费者消费。通过设置一定的定时时间可以实现分布式场景的延时调度触发效果。

顺序消息:

顺序消息是 RocketMQ 提供的一种高级消息类型,支持消费者按照发送消息的先后顺序获取消息,从而实现业务场景中的顺序处理。

二、RocketMQ 系统架构

  

2.1 Producer

Producer 是消息生产者,负责生产消息。Producer 通过 MQ 的负载均衡模块选择相应的 Broker 集群队列进行消息投递,投递的过程支持快速失败并且低延迟。

RocketMQ 中的消息生产者都是以生产者组(Producer Group)的形式出现的,生产者组是同一类生产者的集合,这类 Producer 发送相同 Topic 类型的消息。

2.2 Consumer

Consumer 是消息消费者,负责消费消息。一个消息消费者会从 Broker 服务器中获取到消息,并对消息进行相关业务处理。

RocketMQ 中的消息消费者都是以消费者组(Consumer Group)的形式出现的,消费者组是同一类消费者的集合,这类 Consumer 消费的是同一个 Topic 类型的消息。消费者组使得在消息消费方面,实现负载均衡和容错的目标变得非常容易。

  

消费者组中 Consumer 的数量应该小于等于订阅 Topic 的 Queue 数量,如果超出 Queue 数量,则多出的 Consumer 将不能消费消息。

  

不过,一个 Topic 类型的消息可以被多个消费者组同时消费。
 

2.3 Name Server

NameServer 是一个 Broker 与 Topic 路由的注册中心,支持 Broker 的动态注册与发现。

NameServer 主要包括两个功能:

  • Broker 管理:接受 Broker 集群的注册信息并且保存下来作为路由信息的基本数据,提供心跳检测机制,检查 Broker 是否还存活。
  • 路由信息管理:每个 NameServer 中都保存着 Broker 集群的整个路由信息和用于客户端查询的队列信息。Producer 和 Conumser 通过 NameServer 可以获取整个 Broker 集群的路由信息,从而进行消息的投递和消费。

路由注册:

NameServer 通常也是以集群的方式部署,不过 NameServer 是无状态的,即 NameServer 集群中的各个节点间是无差异的,各节点间相互不进行信息通讯。在 Broker 节点启动时,轮询 NameServer 列表,与每个 NameServer 节点建立长连接,发起注册请求。在 NameServer 内部维护着一个 Broker 列表,用来动态存储 Broker 的信息。

Broker 节点为了证明自己是活着的,为了维护与 NameServer 间的长连接,会将最新的信息以心跳包的方式上报给 NameServer,每50秒发送一次心跳。心跳包中包含 BrokerIld、Broker 地址、Broker 名称、Broker 所属集群名称等等。NameServer 在接收到心跳包后,会更新心跳时间戳,记录这个 Broker 的最新存活时间。
 

路由剔除:

由于 Broker 关机、宕机或网络抖动等原因,NameServer 没有收到 Broker 的心跳,NameServer 可能会将其从 Broker 列表中剔除。

NameServer 中有一个定时任务,每隔10秒就会扫描一次 Broker 表,查看每一个 Broker 的最新心跳时间戳距离当前时间是否超过120秒,如果超过,则会判定 Broker 失效,然后将其从 Broker 列表中剔除。

路由发现:

RocketMQ 的路由发现采用的是 Pull 模型。当 Topic 路由信息出现变化时,NameServer 不会主动推送给客户端,而是客户端定时拉取主题最新的路由。默认客户端每30秒会拉取一次最新的路由。
 

客户端 NameServer 选择策略:

客户端在配置时必须要写上 NameServer集群的地址,那么客户端到底连接的是哪个 NameServer 节点呢?客户端首先会生成一个随机数,然后再与 NameServer 节点数量取模,此时得到的就是所要连接的节点索引,然后就会进行连接。如果连接失败,则会采用 round-robin 策略,逐个尝试着去连接其它节点。

首先采用的是随即策略,失败后采用轮询策略。

2.4 Broker

Broker 充当着消息中转角色,负责存储消息、转发消息。

Broker 在 RocketMQ 系统中负责接收并存储从生产者发送来的消息,同时为消费者的拉取请求作准备。Broker 同时也存储着消息相关的元数据,包括消费者组消费进度偏移 offset、主题、队列等。

Broker 功能模块:

  • Remoting Module:整个 Broker 的实体,负责处理来自 clients 端的请求。
  • Client Manager:客户端管理器。负责接收、解析客户端(Producer/Consumer)请求,管理客户端。例如,维护 Consumer 的 Topic 订阅信息
  • Store Service:存储服务。提供方便简单的 API 接口,处理消息存储到物理硬盘和消息查询功能。
  • HA Service:高可用服务,提供 Master Broker 和 Slave Broker 之间的数据同步功能。
  • Index Service:索引服务。根据特定的 Message key,对投递到 Broker 的消息进行索引服务,同时也提供根据 Message Key 对消息进行快速查询的功能。

集群部署:

为了增强 Broker 性能与吞吐量,Broker 一般都是以集群形式出现的。各集群节点中可能存放着相同 Topic 的不同 Queue。每个 Broker 集群节点可以进行横向扩展,即将 Broker 节点再建为一个 HA 集群,解决单点数据丢失问题。

Broker 节点集群是一个主从集群,即集群中具有 Master 与 Slave 两种角色。

  • Master 负责处理读写操作请求,而 Slave 仅负责读操作请求(Master 宕机后,Slave也负责读写操作)。
  • 一个 Master 可以包含多个 Slave,但一个 Slave 只能隶属于一个 Master。
  • Master 与 Slave 的对应关系是通过指定相同的 BrokerName、不同的 Brokerld 来确定的。Brokerld 为0表示 Master,非0表示 Slave。
  • 每个 Broker 与 NameServer 集群中的所有节点建立长连接,定时注册 Topic 信息到所有 NameServer。
     

2.5 工作流程

  1. 启动 NameServer,NameServer 启动后开始监听端口,等待 Broker、Producer、Consumer 连接。
  2. 启动 Broker 时,Broker 会与所有的 NameServer 建立并保持长连接,然后每30秒向 NameServer 定时发送心跳包。
  3. 收发消息前,可以先创建 Topic,创建 Topic 时需要指定该 Topic 要存储在哪些 Broker上,当然,在创建 Topic 时也会将 Topic 与 Broker 的关系写入到 NameServer 中。不过,这步是可选的,也可以在发送消息时自动创建 Topic。Topic 的创建模式:
    1. 集群模式:该模式下创建的 Topic 在该集群中,所有 Broker 中的 Queue 数量是相同的。
    2. Broker 模式::该模式下创建的 Topic 在该集群中,每个 Broker 中的 Queue 数量是可以不同。
    3. 自动创建 Topic 时,默认采用的是 Broker 模式,会为每个 Broker 默认创建4个 Queue。
  4. Producer 发送消息,启动时先跟 NameServer 集群中的其中一台建立长连接,并从NameServer 中获取路由信息,即当前发送的 Topic 的 Queue 与 Broker 的地址(IP+Port)的映射关系。然后根据算法策略从队列中选择一个 Queue,与队列所在的 Broker 建立长连接从而向 Broker 发消息。当然,在获取到路由信息后,Producer 会首先将路由信息缓存到本地,再每30秒从 NameServer 更新一次路由信息。
  5. Consumer 跟 Producer 类似,跟其中一台 NameServer 建立长连接,获取其所订阅 Topic 的路由信息,然后根据算法策略从路由信息中获取到其所要消费的 Queue,然后直接跟 Broker 建立长连接,开始消费其中的消息。Consumer 在获取到路由信息后,同样也会每30秒从 NameServer 更新一次路由信息。不过不同于 Producer 的是,Consumer 还会向  Broker 发送心跳,以确保 Broker 的存活状态。
     

三、RocketMQ 入门

3.1 RocketMQ 安装

(1)RocketMQ 下载

进入 RocketMQ 官网

点击 Download 进入下载界面,如下。选择对应的版本下载即可,如 rocketmq-all-4.8.0-bin-release.zip

将下载完成的文件上传到 Linux 服务器中,并使用以下命令完成解压

unzip rocketmq-all-4.8.0-bin-release.zip

解压后目录如下:

(2)修改配置

修改 RocketMQ 配置,需要修改 runserver.sh 文件和 runbroker.sh 文件中的初始内存。

runserver.sh 文件

修改为:

-server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

runbroker.sh 文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TwoYellowGuns

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值