目录
一. 为什么选择了 RocketMQ ?
二. RocketMQ 介绍
名词说明
1. Topic (主题)
1.1 Topic 核心作用
1.2 Topic 常见问题
2. Tag (标签)
3. Queue (队列)
3.1 Queue 读写队列
4. Message (消息)
4.1 Message 类型
5. Producer (生产者)
6. Consumer(消费者)
7. NameServer (名字服务器)
8. Broker (代理服务器)
8.1 Broker 几个重要的子模块
三. RocketMQ 工作流程
集群之间交互方式
一. 为什么选择了 RocketMQ ?
在阿里孕育 RocketMQ 的雏形时期,我们将其用于异步通信、搜索、社交网络活动流、数据管道,贸易流程中。随着我们的贸易业务吞吐量的上升,源自我们的消息传递集群的压力也变得紧迫。
根据我们的研究,随着队列和虚拟主题使用的增加,ActiveMQ IO模块达到了一个瓶颈。我们尽力通过节流、断路器或降级来解决这个问题,但效果并不理想。于是我们尝试了流行的消息传递解决方案Kafka。不幸的是,Kafka不能满足我们的要求,其尤其表现在低延迟和高可靠性方面,详见这里。在这种情况下,我们决定发明一个新的消息传递引擎来处理更广泛的消息用例,覆盖从传统的pub/sub场景到高容量的实时零误差的交易系统。
Apache RocketMQ 自诞生以来,因其架构简单、业务功能丰富、具备极强可扩展性等特点被众多企业开发者以及云厂商广泛采用。历经十余年的大规模场景打磨,RocketMQ 已经成为业内共识的金融级可靠业务消息首选方案,被广泛应用于互联网、大数据、移动互联网、物联网等领域的业务场景。
二. RocketMQ 介绍
在正式学习使用RocketMQ之前, 要了解几个区别于标准消息中间件的概念. 如Group、Topic、Queue等。
系统组成则由 Producer(生产者)、Consumer(消费者)、Broker(服务代理器)、NameServer(名称服务器)等组件组成。
名词说明
1. Topic (主题)
Topic主题是RocketMQ中消息传输和存储的顶层存储, 表示一类消息的集合. 每个topic 主题包含若干条message . 每条message 只能属于一个topic主题.
可以理解为消息的分类. 但主题是一个逻辑概念,并不是实际的消息容器。现在垃圾都提倡分类了. 消息可不能一个topic干到底啊.
1.1 Topic 核心作用
- 定义数据的分类隔离: 将不同业务类型的数据拆分到不同的主题中管理. 通过主题实现存储隔离性, 订阅隔离性.
- 定义数据的身份和权限 : RocketMQ 本身是匿名无身份的. 同一类的消息使用相同主题来做身份识别和权限管理.
1.2 Topic 常见问题
- Topic 拆分过细, 别有的小伙伴听说是分类用的. 于是把主题拆的很细, 一个用户一个Topic 一笔交易是一个Topic. 太壮观了👍. 这样会消耗大量的主题资源, 造成系统负载过重.
- Topic 拆分过粗, 上面小编写了不能拆分过细, 那么是不是越粗越好呢? 甚至就不拆了. 这样也不好, 会导致业务隔离性差 ,不利于独立运维和故障处理. 遇到问题排查起来会费劲很多.
- Topic 线上开启自动化,RocketMQ提供了自动化创建主题的功能. 在开发阶段用的是一个字 爽 , 上线别忘记关掉啊. 这样过一段时间发现会产生大量的垃圾主题, 这样就无法管理和回收并浪费资源.
2. Tag (标签)
Topic 与 Tag 都是业务上用来归类的标识,区别在于 Topic 是一级分类,而 Tag 可以理解为是二级分类。使用 Tag 可以实现对 Topic 中的消息进行过滤。用于同一主题下区分不同类型的消息。
比如支付消息可以分为: 创建支付订单消息, 支持结果消息, 支持完成消息等. 一条消息可以没有Tag. 标签有助于您代码的干净和连贯.
3. Queue (队列)
相当于Topic 的分区, 用于并行发送和接收消息的. 队列是消息存储和传输的实际容器, 也是RocketMQ 中最小存储单位. 一个Topic中可以包含多个Queue.
3.1 Queue 读写队列
Queue 分为读队列(对于消费者来说) 和 写队列(对于生产者来说) 默认创建数量都是4, 这个读写队列是在逻辑上进心划分得, 在物理上读写是一个队列。 Produce 发送消息进入写队列, Consumer从读队列中获取消息, 一般情况下读写队列数量是一样得。
RocketMQ 中是以Topic为单位进行管理得, 但是实际传输还是Queue ,也就是说无论消息发送还是消费都是到实际得Queue中进行操作。
4. Message (消息)
消息是RocketMQ中最小数据传输单元, 生产者将业务的负载和拓展属性包装成消息发送到RocketMQ服务端,服务端按照相关语义将消息投递到消费端进行消费。
4.1 Message 类型
- 普通消息 ,消息本身无特殊语义,消息之间没有任何关联。 就是发送一条普通的消息。
- 批量消息, 就是将多个消息同时发送过去, 减少网络请求次数。多个普通消息同时发送,这就是批量消息。普通消息和批量消息比较简单, 没有复杂的逻辑,就是将消息发送出去。
- 顺序消息, 就是生产者发送消息的顺序跟消费者消费消息的顺序一样。
- 延迟消息, 就是生产者发送消息后,消费者不会立马消费。而是等待一定时间之后再消费。
- 事务消息, RocketMQ支持分布式事务消息,支持应用数据库更新和消息调用的一致性保障。
- 请求应答消息, 这种消息比较有意思,类似RPC模式。 生产者发送消息之后可以阻塞等待消费者消费这个消息的之后返回的结果。
- 重试消息, 这个并不是我们业务中主动发送的。 而是指消费者消费消息失败之后, 会间隔一段时间之后再次消费这条消息。
- 死信消息, 就是指一条信息最终无法被正常消费, 那么这条消息就称为死信消息。
- 同步消息, 就是指生产者发送消息后, 等待服务器响应消息结果。
- 异步消息, 有了同步消息,那么肯定少不了异步消息,异步消息就是生产者发送消息后,不需要等待服务器响应消息结果,直接返回。 对同步异步不太清楚的可以阅读一下为什么要选择MQ? 有什么好处
- 单项消息, 所谓单项消息就是生产者发送到服务端就不管了。无论成功失败都不在理会。
5. Producer (生产者)
生产者就是发送消息的角色。 通过nameserver的负载均衡模块选择相应的Broker集群队列中进行消息投递。
6. Consumer(消费者)
消费者也称为订阅者, 负责从Topic中接收并消费消息。
7. NameServer (名字服务器)
NameServer是一个简单的Topic路由注册中心。支持Topic ,Broker的动态注册与发现。 主要两个功能,
Broker管理, NameServer接收Broker集群的注册信息并保存下来作为路由信息的基本数据, 然后提供心跳检测机制,检测Broker是否存活。
路由信息管理, 每个NameServer将保存关于Broker集群的整个路由信息和用于客户端查询队列信息。 Producer 和 Consumer 通过NameServer 就可以知道整个Broker 集群的路由信息, 从而进行消息的投递和消费。
NameServer 通常是以集群的方式部署的, NameServer 是无状态的, 有什么有缺点:
优点: NameServer 集群搭建简单,扩展简单。
缺点: 对于Broker ,必须明确指出所有的NameServer 地址。 否则未指出的地址将不会被注册。也正因为如此,NameServer不能随意的扩容, 因为,若Broker不重新配置, 新增的NameServer 对于Broker来说是不可见的, 也不会向 这个NameServer进行注册。
8. Broker (代理服务器)
Broker 主要负责消息的存储,投递和查询以及服务高可用保证。 是一个消息中转角色,负责存储消息,转发消息, 在RocketMQ中负责接收存储从生产者发来的消息,同时也为消费者拉去消息做准备。
8.1 Broker 几个重要的子模块
- 远程处理模块, Broker入口,处理来自客户端的请求。
- 客户端管理,管理客户端(包括生产者和消费者), 维护消费者的主题订阅。
- 存储服务, 提供在物理磁盘上存储和查询消息简单的API.
- HA 服务, 提供冲Broker间数据同步。
- 索引服务, 通过指定键为消息建立索引并提供快速查找消息。
三. RocketMQ 工作流程
交互方式
- Broker Master和Broker Slave 是主从结构,会执行数据的同步。
- 每个Broker 与NameServer 集群中所有的节点建立长连接,定时注册Topic信息到所有的NameServer
- Producer 与 NameServer 随机任意一个节点建立长连接,定期获取Topic 的路由信息。 并于提供Topic的Broker Master 建立长连接, 定期给Broker发送心跳信息。
- Producer 只能将消息发送到Broker Master, 但是Consumer 同时和Broker Master 和Broker Slave 建立长连接, 即可以从Master 订阅消息,也可以从Slave 订阅消息。
ps: 文章中官方描述来源于 rocketmq.apache.org