Apache RocketMQ 入门介绍和整体架构图

Apache RocketMQ 入门介绍和整体架构图

经验文章nimo972025-02-24 15:55:377A+A-

RocketMQ 是阿里巴巴的分布式消息中间件,在 2012 年开源,在 2017 年成为 Apache 顶级项目。

RocketMQ是一个纯Java、分布式、队列模型的开源消息中间件,前身是MetaQ,是阿里参考Kafka特点研发的一个队列模型的消息中间件,后开源给apache基金会成为了apache的顶级开源项目,具有高性能、高可靠、高实时、分布式特点。


RocketMQ在阿里集团也被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,binlog分发等场景。


一、RocketMQ 集群架构图

RocketMQ 主要有四大核心组成部分:NameServer、Broker、Producer以及Consumer四部分。


(1)Name Server 集群

Name Server 集群部署,但是节点之间并不会同步数据,因为每个节点都会保存完整的数据。因此单个节点挂掉,并不会对集群产生影响。路由信息在 Name Server 集群中数据一致性采取的最终一致性


(2)Broker

消息存储服务器,负责存储消息、转发消息,分为两种角色:Master 与 Slave,上图中呈现的就是 2 主 2 从的部署架构。

Broker 采用主从集群,实现多副本存储和高可用。每个 Broker 节点都要跟所有的 Name Server 节点建立长连接,Broker在启动的时候会注册自己配置的topic信息到Name Server集群的每一台机器中。即每一台Name Server都有该Broker的topic的配置信息。master与master之间无连接,master与slave之间有连接。

跟所有 Name Server 建立连接,就不会因为单个 Name Server 挂了影响 Broker 使用。Broker 主从模式中, Slave 节点主动从 Master 节点拉取消息。


所有 Broker,包含 Slave 服务器每隔 30s 会向 Name Server 发送心跳包,心跳包中会包含存在在 Broker 上所有的 topic 的路由信息。

具有上亿级消息堆积能力,同时可严格保证消息的有序性。


(3)消息生产者 Producer

Producer 跟 Name Server 的任意一个节点建立长连接,定期从 Name Server 拉取 topic 路由信息。Producer 是否采用集群,取决于它所在的业务系统。


RocketMQ 提供了三种方式发送消息:同步、异步和单向。

  • 同步发送:同步发送指消息发送方发出数据后会在收到接收方发回响应之后才发下一个数据包。一般用于重要通知消息,例如重要通知邮件、营销短信。
  • 异步发送:异步发送指发送方发出数据后,不等接收方发回响应,接着发送下个数据包,一般用于可能链路耗时较长而对响应时间敏感的业务场景,例如用户视频上传后通知启动转码服务。
  • 单向发送:单向发送是指只负责发送消息而不等待服务器回应,且没有回调函数触发,适用于某些耗时非常短但对可靠性要求并不高的场景,例如日志收集。


(4)消息消费者 Consumer

Consumer 跟 Name Server 的任意一个节点建立长连接,定期从 Name Server 拉取 topic 路由信息。Consumer 是否采用集群,取决于它所在的业务系统。


Consumer 由用户部署,支持PUSH和PULL两种消费模式,支持集群消费和广播消息,提供实时的消息订阅机制。

  • Pull:拉取型消费者(Pull Consumer)主动从消息服务器拉取信息,只要批量拉取到消息,用户应用就会启动消费过程,所以 Pull 称为主动消费型。
  • Push:推送型消费者(Push Consumer)封装了消息的拉取、消费进度和其他的内部维护工作,将消息到达时执行的回调接口留给用户应用程序来实现。所以 Push 称为被动消费类型,但从实现上看还是从消息服务器中拉取消息,不同于 Pull 的是 Push 首先要注册消费监听器,当监听器触发后才开始消费消息。


Producer 和 Consumer 只跟任意一个 Name Server 节点建立连接,因为 Broker 会向所有 Name Server 注册 topic 信息,所以每个 Name Server 保存的数据其实是一致的。


RocketMQ 中一次完整的通信流程是怎样的?

Producer 与 NameServer集群中的其中一个节点(随机选择)建立长连接,定期从 NameServer 获取 Topic 路由信息,并向提供 Topic 服务的 Broker Master 建立长连接,且定时向 Broker 发送心跳。


Producer 只能将消息发送到 Broker master,但是 Consumer 则不一样,它同时和提供 Topic 服务的 Master 和 Slave建立长连接,既可以从 Broker Master 订阅消息,也可以从 Broker Slave 订阅消息。


二、消息队列(MessageQueue)

Producer 发送的消息会在 Broker 的 MessageQueue 中保存,如下图:



有了 MessageQueue ,Topic 就可以在 Broker 中实现分布式存储,如上图,Broker 集群中保存了 4 个MessageQueue,这些 MessageQueue 保存了 Topic1-Topic3 这三个 Topic 的消息。


MessageQueue 类似于 Kafka 中的 Partition,有了 MessageQueue,Producer 可以并发地向 Broker 中发送消息,Consumer 也可以并发地消费消息。


默认 Topic 可以创建的 MessageQueue 数量是 4,Broker 可以创建的 MessageQueue 数量是 8, RocketMQ 选择二者中数量小的,也就是 4。不过这两个值都可以配置。


三、消费者(Consumer)

RocketMQ的消费模式如下图:


图中,Topic1 的消息写入了两个 MessageQueue,两个队列保存在 Broker1 和 Broker2 上。


RocketMQ 通过 Consumer Group 实现消息广播。比如上图中有两个消费者组,每个消费者组有两个消费者。


一个消费者可以消费多个 MessageQueue,但是同一个 MessageQueue 只能被同一个消费者组的一个消费者消费。比如 MessageQueue0 只能被 Consumer Group1 中的 Consumer1 消费, 不能被 Consumer2 消费。这一点,和Kafka 的消费模式基本一致。


四、Broker 高可用集群

Broker 集群如下图:


Broker 通过主从集群来实现消息高可用。跟 Kafka 不同的是,RocketMQ 并没有 Master 节点选举功能,而是采用多 Master 多 Slave 的集群架构。Producer 写入消息时写入 Master 节点,Slave 节点主动从 Master 节点拉取数据来保持跟 Master 节点的数据一致。


Consumer 消费消息时,既可以从 Master 节点拉取数据,也可以从 Slave 节点拉取数据。 到底是从 Master 拉取还是从 Slave 拉取取决于 Master 节点的负载和 Slave 的同步情况 。如果 Master 负载很高,Master 会通知 Consumer 从 Slave 拉取消息,而如果 Slave 同步消息进度延后,则 Master 会通知 Consumer 从 Master 拉取数据。总之,从 Master 拉取还是从 Slave 拉取由 Master 来决定。


如果 Master 节点发生故障,RocketMQ 会使用基于 raft 协议的 DLedger 算法来进行主从切换。

Broker 每隔 30s 向 Name Server 发送心跳,Name Server 如果 120s 没有收到心跳,就会判断 Broker 宕机了。


五、消息领域模型

主要分为Message、Topic、Queue、Offset以及Group这几部分。


(1)Message

Message(消息)就是要传输的信息。

一条消息必须有一个主题(Topic),主题可以看做是你的信件要邮寄的地址。

一条消息也可以拥有一个可选的标签(Tag)和额处的键值对,它们可以用于设置一个业务 Key 并在 Broker 上查找此消息,以便在开发期间查找问题。


(2)Topic

Topic(主题)可以看做消息的规类,它是消息的第一级类型。比如一个电商系统可以分为:交易消息、物流消息等,一条消息必须有一个 Topic 。

Topic 与生产者和消费者的关系非常松散,一个 Topic 可以有0个、1个、多个生产者向其发送消息,一个生产者也可以同时向不同的 Topic 发送消息。

一个 Topic 也可以被 0个、1个、多个消费者订阅。


(3)Message Queue

Message Queue(消息队列),主题被划分为一个或多个子主题,即消息队列。

一个 Topic 下可以设置多个消息队列,发送消息时执行该消息的 Topic ,RocketMQ 会轮询该 Topic 下的所有队列将消息发出去。

Queue 是消息的物理管理单位。一个Topic下可以有多个Queue,Queue的引入使得消息的存储可以分布式集群化,具有了水平扩展能力。


(4)Offset

在RocketMQ 中,所有消息队列都是持久化,长度无限的数据结构,所谓长度无限是指队列中的每个存储单元都是定长,访问其中的存储单元使用Offset 来访问,Offset 为 Java long 类型,64 位,理论上在 100年内不会溢出,所以认为是长度无限。

也可以认为 Message Queue 是一个长度无限的数组,Offset 就是下标。


(5)标签(Tag)

为消息设置的标志,用于同一主题下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签。标签能够有效地保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。消费者可以根据Tag实现对不同子主题的不同消费逻辑,实现更好的扩展性。


(6)生产者组(Producer Group)

同一类Producer的集合,这类Producer发送同一类消息且发送逻辑一致。如果发送的是事务消息且原始生产者在发送之后崩溃,则Broker服务器会联系同一生产者组的其他生产者实例以提交或回溯消费。


(7)消费者组(Consumer Group)

同一类Consumer的集合,这类Consumer通常消费同一类消息且消费逻辑一致。消费者组使得在消息消费方面,实现负载均衡和容错的目标变得非常容易。要注意的是,消费者组的消费者实例必须订阅完全相同的Topic。RocketMQ 支持两种消息模式:集群消费(Clustering)和广播消费(Broadcasting)。


(8)集群消费(Clustering)

集群消费模式下,相同Consumer Group的每个Consumer实例平均分摊消息。


(9)广播消费(Broadcasting)

广播消费模式下,相同Consumer Group的每个Consumer实例都接收全量的消息。


六、消息中间件应用场景

是阿里开源的一款MQ中间件,早期阿里内部为了将交易核心数据的流转,需要一款能存储海量消息并且支持顺序消息的MQ,所以内部开始了研发了叫MetaQ的中间件,到了2012年经过版本迭代后包装成了RocketMQ并开源出来。在阿里内部经过历年双十一大促和内部成千上万个应用的检验,RocketMQ已经是一款性能高,可用性高,稳定性强的一款消息中间件了。


下面,我们看看RocketMQ的应用场景:

业务解耦:比如销售系统在用户支付成功之后会更新订单状态,并且会将下单时锁定的库存进行扣减。传统单体项目可能是一条业务线走到底,但随着互联网发展,在业务单一原则下很多服务只处理一类型的业务了,这样MQ就可以充当业务解耦的作用,支付系统在支付成功后发送一条消息告知消费者交易成功,那么订阅这个队列的消费者就可以收到,进行订单更新,进行库存扣减了。


削峰填谷:这个比较好理解,在高并发的场景下,某些业务不是必须马上执行的,利用MQ可以有效降低系统压力。比如登陆送积分业务,如果有1000人同时登陆系统,如果不使用MQ就可能是登陆后进行积分增加,记录日志等,串行化的处理业务会增加登陆响应时间,这是使用MQ可以将并发量转换到了MQ上,而积分系统可以按照自己的吞吐量去消化掉这些业务,而不是正面抗高并发的请求,将波峰的流量平缓的处理掉。


异步化:从上面两点都可以看出,不管是业务解耦合还是削峰填谷都不是串行化的执行,生产者和消费者其实是异步化的。


欢迎关注《Apache RocketMQ 深入浅出》系列文章,架构师将循序渐进地讲解Apache RocketMQ的开发实践。

点击这里复制本文地址 以上内容由nimo97整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

尼墨宝库 © All Rights Reserved.  蜀ICP备2024111239号-7