RocketMQ基本概念
- 前言
- RocketMQ中的基本概念
- 主题(Topic)
- 标签(Tag)
- 生产者(Producer)
- 生产者组(Producer-Group)
- 消费者 (Consumer)
- 消费者组(Consumer-Group)
- 消息代理(Broker)
- 消息队列(Queue)
- Broker - Topic - Queue的关联以及分片的概念
- 分片
- 命名服务(NameServer)
前言
在前文简单介绍了RocketMQ的起源以及优缺点
,本文旨在介绍其相关的基本概念
,诸如:消费者(Consumer),生产者(Producer),消息代理(Broker),主题(Topic)等。
当然大家也可以查看RocketMQ的官网的官方文档
RocketMQ中的基本概念
主题(Topic)
每个消息(Message)
都必须要有一个主题(Topic)
,该主题标识了消息的类型
,RocketMQ
会根据该类型,将同类型的消息放到一起
。
比如我们有一个仓库的管理系统
,这里有两个子模块:出库模块
和入库模块
出库模块会记录货物的出库信息
,那么我们可以创建一个出库
的主题,用于标识出库消息
同样的对于入库模块
也可以创建一个入库
的主题
如下图所示
标签(Tag)
用于区分同一主题
下不同类型
的消息,当同一主题下的消息需要区分时
,那么我们可以使用该标签将消息区分得更加精细
比如我的出库量很大,全国各地的货物都有,那么我们可以在出库消息中的再加一个地区的标签,用于区分
生产者(Producer)
这个比较容易理解,产生消息的模块
即为消息的生产者(Producer)
比如我们上面的出库模块和入库模块
都是消息的生产者
生产者组(Producer-Group)
可以生产同一主题消息的多个生产者
,我们称之为生产者组 Producer-Group
这里需要注意的是,一个生产者可以生产多个主题的消息的
,并不是一个生产者只能生产一种主题的消息。
比如有的仓库可能出库的时候,不仅要产生出库消息
,还要收费,还要产生一个支付消息给支付模块
。
消费者 (Consumer)
消息的处理者
就是消费者(Consumer)
。
当一个消费者订阅了某个主题
的消息,那么就会去获取该主题下的消息并进行处理
,也就是我们说的消费消息
。
当然,也可以精确到订阅某个主题下的标签
,从而处理带有这种标签的消息
。
比如我们上述的出库消息,假设我们还有一个接收该出库消息的模块
,用于持久化消息
,将出库消息里面的出库信息写入
到我们的数据库
中,称之为持久化模块
。
那么该模块会从RocketMQ中获取出库
这个主题下的消息。然后进行持久化处理。
消费者组(Consumer-Group)
可以处理同一主题消息的多个消费者
,我们称之为消费者组(Consumer-Group)
与前面生产者类似
值得注意的是,消费者一般是以消费者组
出现的。
还有就是与生产者类似,消费者可以订阅多个主题
下的消息进行消费。
但是一组消费者需要订阅相同的主题
,否则会造成消费紊乱
,甚至消息丢失
。
消费者组的优点在于容错和负载均衡
,
因为存在多个消费者,当一个消费者模块瘫痪时
,其他消费者会继续消费消息
,不会造成消息的堆积。
并且由于存在多个消费者,消息会被比较均匀地分配给每个消费者
,从而达到负载均衡。(并不是以消息为单位分配
,而是以后面的Queue
为单位分配)
消息代理(Broker)
负责存储以及转发
消息。
生产者产生的消息会先放在这里,消费者组也是从这里拿消息。
如以下这样:
可以简单的理解为一个存储消息主机
。
消息队列(Queue)
存放消息的物理实体
,同时也是消息物理管理单位
。
我们知道消息是存放在Broker
上的,但是其存形式并不是以单个消息存在
,而是以Queue
的形式存在的。
同一主题下可以存在多个Queue
,每个Queue
中的消息数量大致相等
,如以下这样
值得注意的是:生产者产生消息是放到Queue中的,消费者消费消息也是在Queue中进行
。也就是生产者和消费者的操作都直接与Queue
直接挂钩。
并且一个Queue
只能被同一消费者组中的一个消费者
消费,也就不存在同一消费者组中的两个消费者消费同一Queue
的情况。
Broker - Topic - Queue的关联以及分片的概念
分片
在这里再介绍一下分片
的概念。
在上面的描述中,我们知道一个Broker约等于一个主机
,当我们有多个RocketMQ的主机(集群)
时,这些主机上的主题可能是相同的
。
也就是我的Broker1上存在有出库和入库类型两个主题
,Broker2
上也可以存在这两个主题
。我们把同一主题,不同Broker
里的主题
称之为该主题的一个分片
。
用图表示会更好理解:
在上图中我们的出库主题存在于两个Broker上
,那么每个Broker下的出库主题都是该主题的一个分片
。
命名服务(NameServer)
在知道上述Broker、Topic
的关系之后,我们会有这么一个疑问:消费者和生产者该怎么确定哪些Topic存在于哪些主题上呢
?
以消费者
举例:我来消费订阅的主题下的消息,我要去哪些Broker下获取消息消费
,我怎么知道哪些Borker中有我订阅的主题
呢?
而这件事就是我们的NameServer
的主要功能之一。
NameServer
是一个Broker与Topic路由
的注册
中心,其的作用是提供轻量级的名称服务
,维护Broker、Producer和Consumer的路由信息,协调各个角色的通信
等。
其具体功能可大致分为以下几部分:
-
路由注册
:Broker
在启动时,会向NameServer集群中
的每个
节点注册
自己的信息,并定期发送心跳包
,更新
自己的状态。NameServer
会维护一个Broker表
,记录Broker的信息和存活时间
。 -
路由剔除
:如果Broker关闭或者异常
,NameServer会检测到连接断开或者心跳超时
,然后将该Broker从Broker表中移除
,避免给客户端提供错误的路由信息。 -
路由发现
:Producer和Consumer
在发送或者消费
消息时,需要根据Topic获取路由信息
,包括Topic
下有哪些Queue
,这些Queue分布在哪些Broker上
等。NameServer
会根据Broker表
提供最新的路由信息给客户端
,客户端也会定期从NameServer拉取路由信息
,保证数据的最终一致性。 -
动态扩展
: 当新的 Broker
加入RocketMQ
系统时,或者有 Broker 离开系统时
,NameServer
负责更新系统的路由信息
,而不需要重新启动
从而实现动态扩展。这使得RocketMQ
具备了动态扩展的能力
,系统可以适应不同规模和变化的需求。 -
负载均衡
:NameServer
为消息队列的负载均衡
提供了支持。它会记录每个 Broker 上的队列信息
,帮助系统实现消息的均匀分发
,确保每个队列的负载相对均衡
。这有助于提高整个系统的性能和稳定性。
后续的消息的种类以及其消费模式
我就放在下一篇文章里了。