RocketMQ

65 阅读8分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

RocketMQ

消息中间件是分布式系统中重要的组件,主要解决应用解耦异步消息流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。

目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Kafka,RocketMQ 等。

RocketMQ 是一个队列模型的消息中间件,具有高性能、高可靠、高实时、分布式特点。由阿里巴巴研发,借鉴参考了 JMS 规范的 MQ 实现,参考了优秀的开源消息中间件 Kafka,并且结合阿里实际业务需求,在天猫双十一的场景,实现业务削峰,分布式事务的优秀框架。

特性

  • 具有高性能、高可靠、高实时、分布式( Producer、Consumer、队列都可以分布式 )特点;
  • 底层采用Netty NIO框架实现数据通信;
  • 内部使用更轻量级的 NameServer 进行网络路由,提高服务性能,并支持消息失败重试机制;
  • 支持集群模式、消费者负载均衡、水平扩展能力,支持广播模式;
  • 采用零拷贝原理,顺序写盘、支持亿级消息堆积能力;
  • 提供丰富的消息机制,比如顺序消息、事务消息;

RocketMQ 核心概念

消息模型 Message Model

RocketMQ 主要由 ProducerBrokerConsumer 三部分组成. Producer 负责生产消息,Consumer 负责消费消息,Broker 负责存储消息

Broker 在实际部署过程中对应一台服务器,每个 Broker 可以存储多个 Topic 的消息,每个 Topic 的消息也可以分片存储于不同的 Broker。

Message Queue 用于存储消息的物理地址,每个 Topic 中的消息地址存储于多个 Message Queue 中。
ConsumerGroup 由多个Consumer 实例构成。

消息生产者 Producer

Producer 负责生产消息,一般由业务系统负责生产消息。生产者会把业务应用系统里产生的消息发送到 broker 服务器。

RocketMQ 提供多种发送方式,同步发送异步发送单向发送。同步和异步方式均需要 Broker 返回确认信息,单向发送则不需要。

几种方式的区别:

  • 同步消息:客户端将消息发送到 Master Broker 后,需要等 Master Broker 将消息同步到对应的 Slave Broker 后,Broker 才会响应客户端。这种方式响应客户端比较慢,但具有较强的数据安全性,数据丢失风险小。
  • 异步消息:客户端将消息发送到 Master Broke r后,只要 Master Broker 将消息处理完,Broker 就响应客户端,无需等待 Master Broker 将消息同步到对应的 Slave Broker。这种方式对客户端响应快,但存在一定的风险性:在 Master Broker 处理完消息响应客户端后就宕机,此时消息可能会发生丢失。
  • 单向消息:客户端只负责消息发送,不等待 Broker 回应,这种方式效率最高,但消息丢失的风险也最高,一般用在可以容忍消息有一定丢失的场景。

消息消费者 Consumer

Consumer 负责消费消息,一般是后台系统负责异步消费。一个消息消费者会从 Broker 服务器拉取消息、并将其提供给应用程序。

从用户应用的角度而言提供了两种消费形式:拉取式消费( Pull 方式 )、推动式消费 ( Push 方式 )。

  • 拉取式消费:应用通常主动调用 Consumer 的拉消息方法从 Broker 服务器拉消息、主动权由应用控制。

一旦获取了批量消息,应用就会启动消费过程。

  • 推动式消费:Broker 收到数据后会主动推送给消费端,该消费模式一般实时性较高

代理服务器 Broker Server

Broker 是消息存储服务器,同时也是消息中转角色,负责存储+转发消息。

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

Broker 在实际部署过程中对应一台服务器,每个 Broker 可以存储多个 Topic 的消息,每个 Topic 的消息也可以分片存储于不同的 Broker。

Broker 分为两种角色:Master 与 Slave。主服务 Master 承担读写操作,从服务器 Slave 作为一个备份。

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

名字服务 Name Server

NameServer 是 Topic 的路由注册中心,为客户端根据 Topic 提供路由服务,从而引导客户端向 Broker 发送消息。

生产者或消费者能够通过 NameServer 查找各主题相应的 Broker 的 IP 列表。

多个 NameServer 实例组成集群,但相互独立,它们之间没有信息交换。

消息 Message

Message 其实就是要发送的信息内容,生产和消费数据的最小单位每条消息必须属于一个主题 Topic, 并且也只能属于一个主题

RocketMQ 中每个消息拥有唯一的 Message ID,且可以携带具有业务标识的 Key。系统提供了通过Message ID 和 Key 查询消息的功能。

主题 Topic

主题是一类消息的集合,是 RocketMQ 进行消息订阅的基本单位

Topic 可以理解为对消息的分类,Topic 与 Message 之间的关系是一对多的关系,即一个 Topic 可以有多个 Message,但是一个 Message 只能属于一个 Topic。

标签 Tag

标签是为消息设置的标志,用于同一主题下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签。

标签能够有效地保持代码的清晰度和连贯性,并优化 RocketMQ 提供的查询系统。消费者可以根据 Tag 实现对不同子主题的不同消费逻辑,实现更好的扩展性。

可以简单理解为:Topic 主题是消息的大分类,而标签 Tag 则是大分类下的小分类

队列 Queue

队列是存储消息的物理实体,一个消息进入一个 Topic 后,会被分到一个 Queue 里面,即消息放在队列里面

一个 Topic 可以包含多个 Queue,每个 Queue 中存的是该 Topic 的消息。

  • 集群模式下:一个 Queue,只能有一个 Comsumer, 一个 Comsumer 可以消费多个 Queue.
  • 广播模式下:一个 Queue,可以有多个 Comsumer, 一个 Comsumer 可以消费多个 Queue.

生产者组 Producer Group

生产者组是同一类 Producer 的集合,这类 Producer 发送同一类消息发送逻辑一致( 即生产者集群 )。

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

消费者组 Consumer Group

消费者组是同一类 Consumer 的集合,这类 Consumer 通常消费同一类消息消费逻辑一致( 即消费者集群 )。

消费者组使得在消息消费方面,实现负载均衡和容错的目标变得非常容易。要注意的是,消费者组的消费者实例必须订阅完全相同的 Topic

两种消费模式

RocketMQ 支持两种消息模式:集群消费( Clustering )( 默认 )和广播消费( Broadcasting )。

(1) 集群消费

集群消费模式下,相同 Consumer Group 的每个 Consumer 实例平均分摊消息。也就是一个消息只会被一个消费者消费。

例如某个 Topic 有 10 条消息,然后存在两个 Consumer Group,其中一个 Consumer Group A 有 3 个实例,另外一个 Consumer Group B 有 2 个实例,那么 MQ 会将这 10 条消息负载均衡分给两个 Consumer Group,一个 5 条。那么 Consumer Group A 会有 5 条消息,B 也有 5 条。A 有三个 Consumer,再进行负载均衡,那么可能会是 2,2,1 这样进行分配消费。B 有两个 Consumer,那么可能是 3,2 这样进行分配消费。

RocketMQ 天然支持消费者负载均衡,并且负载均衡不仅仅局限于消费者,还有消费者组的负载均衡。集群模式是非常普遍的模式,符合分布式架构的基本理念,即横向扩容,当前消费者如果无法快速及时处理消息时,可以通过增加消费者的个数横向扩容,快速提高消费能力,及时处理挤压的消息。

(2) 广播模式

广播消费模式下,相同 Consumer Group 的每个 Consumer 实例都接收全量的消息。也就是一个消息会被所有消费者消费

例如某个 Topic 有 1 条消息,其中一个 Consumer Group 有 3 个实例,另外一个 Consumer Group 有 2 个实例,广播消费的话,消息会被 Consumer Group 中的每个 Consumer 都消费一次,即每个实例都会消费这条消息。

为什么选择 RocketMQ

面试被问为什么选择 RocketMQ 作为你们项目中的消息中间件?可以从下面几点进行回答:

  • RocketMQ集群无单点,可扩展,任意一点高可用,水平可扩展;
  • 支持海量消息堆积能力,消息堆积后,写入低延迟;
  • 支持上万个队列(与ActiveMQ进行对比);
  • 支持消息失败重试机制;
  • 消息可查询;
  • 开源社区活跃;
  • 成熟度(经过双十一考验);