MQ系列3:RocketMQ 架构分析
MQ系列1:消息中间件执行原理
MQ系列2:消息中间件的技术选型
1 背景
我们前面两篇对主流消息队列的基本构成和技术选型做了详细的分析。从本篇开始,我们会专注当下主流MQ之一的RocketMQ。
从他的如下的几个方面去讨论:
- 基础能力(如 组织构成、消息发送、消息存储(持久化)、消息通信、消息消费)
- 功能性方面(如消息堆积、消息回溯、消息追踪、消息过滤),
- 高可用性方面(如 消息顺序性保障、消息幂等性保障、消息安全性保障、消息事务性保障),
- 性能方面(如时效性,单机吞吐率)
1.1 RocketMQ是的基本组件构成
RocketMQ主要有四大核心组成部分:NameServer、Broker、Producer以及Consumer四部分。
- NameServer:Name Server是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。NameServer 是整个 RocketMQ 的 "中央大脑 " ,它是 RocketMQ 的服务注册中心,所以 RocketMQ 需要先启动 NameServer 再启动 Rocket 中的 Broker。
- Broker: 消息服务器,作为Server提供消息核心服务, 它接收并存储Producer生产的消息,也提供消息给Consumer消费。Broker一般会分主从,Master 可读可写,Slave 只读。
- Producer: 消息生产者,消息的发送方,负责生产消息传输给broker。RocketMQ提供了发送:同步、异步和单向(one-way)的多种模式。
- Consumer: 消息消费者,消息的处理方,负责从broker获取消息并进行业务逻辑处理。
另外其他如 Topic、 Message,也是重要的组成部分:
- Topic:主题,发布/订阅模式下的消息统一汇集地,不同生产者向topic发送消息,由MQ服务器分发到不同的订阅者,实现消息的广播
- Message:消息体,根据不同通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输。
2 RocketMQ 消息架构的演进过程
2.1 简单的生产消费模式
根据我们前面所学的内容,消息队列很重要的一个工作就是对生产和消费者进行解耦的过程。有人负责生产,有人负责消费,两者没有直接交互,交给中介者去处理。
比如说系统A会交给系统B去处理一些事情,但是A不想直接跟B有关联,避免耦合太强,就可以通过在A,B中间加入消息队列,A将要任务的事情交给消息队列 ,B订阅消息队列来执行任务。
这种典型的模式是由两个线程和一个队列构成:
- 生产者线程:生产任务,并把任务推送到队列里。
- 消费者线程:从队列里面获取任务,并进行任务处理操作,这就是消费的过程。

目前这种还只是初级版本的 生产-消费者模式,构成了基本的消息队列 。另外为了消息队列的可用性,我们一般会把消费者,队列,生产者放到不同的服务机上,变成分布式消息队列,这样哪怕消费者所在的主机挂了,依旧不影响消息生产。
2.2 Topic模式对消息进行归类
主题(Topic)可以看做消息的归类,我们将消息进行类型划分,相同类型的消息称为一个 Topic。比如我们在淘宝或京东上购买商品的的过程,就可能产生:购物车消息、交易消息、物流消息等,1条消息必然归属于1个 Topic 。
1个 Topic可以有0 ~ n 个生产者向其发送消息;也可以被 0~n 个消费者订阅和处理,于是就有出现了生产者组和消费者组,如下图:

2.3 Broker 集群模式
随着生产者和消费者的不断扩大,原本单一的Broker数据处理的能力始终是有限的(无论是被写入、存储或者被消费),所以这个时候就需要对Broker进行scale out,来分担单机的压力。我们称之为 Broker 集群模式。在 微服务系列、MySQL系列、Redis系列 中,我们已经了解过很多Cluster模式的案例。

这边需要注意,每个Broker 可以包含1个 Broker Master 和 至少 1个Broker Slave ,所以它是主从结构,通过 Data Sync、Async 来进行数据同步。 Producer 只能将消息发送到 Broker Master,但是 Consumer 同时和Broker Master和 Broker Slave 建立长连接,既可以从 Master 订阅消息,也可以从 Slave 订阅消息。
- Broker Master:可以用于消息生产,也可以用于消息消费,并将消息数据 Sync / Async 到Slave。
- Broker Slave:只能用于消息消费。
2.4 使用 NameServer 来进行路由管理
我们既然使用了Broker Cluster模式,那么就会有多个Broker实例。这时候就有新的问题了,producer生产的消息需要发送到哪个Broker中,comsumer又要去哪个Broker里面去取数据,都需要梳理清楚,不然就很混乱。RocketMQ摒弃了业界常用的zookeeper作为注册中心(比如Kafka),而是使用自研的 NameServer 来管理 具有映射关系的路由信息。由它来告诉producer,某个 Topic 的消息可以发给哪些队列,同时告诉consumer可以从哪些队列里面获取你需要的消息。NameServer 也可以有很多个,组成 NameServer 集群。
总得来说,NameServer是一个功能完整的命名服务组件,提供轻量级的服务发现及完整路由信息记录能力,主要包含两个功能:
- Broker 管理,接收来自 Broker 集群的注册请求,提供心跳机制,检测 Broker 是否存活。
- 路由管理,每个 NameServer 持有全部有关 Broker 集群和客户端请求队列的路由信息。
详细运行流程可以参考如下:

上述的流程图比较清晰的描述如下运转流程:
- NameServer 优先启动。NameServer 是整个 RocketMQ 的“中央大脑” ,作为 RocketMQ 的服务注册中心,所以 RocketMQ 需要先启动 NameServer 再启动 Rocket 中的 Broker。
- Broker 启动后,与 NameServer 保持长连接,每 30s 发送一次发送心跳包,来确保Broker是否存活。并将 Broker 信息 ( IP+、端口等信息)以及Broker中存储的Topic信息上报。注册成功后,NameServer 集群中就有 Topic 跟 Broker 的映射关系。
- NameServer 如果检测到Broker 宕机(因为使用心跳机制, 如果检测超120s(两分钟)无响应),则从路由注册表中将其移除。
- 生产者在发送某个主题的消息之前先从 NamerServer 获取 Broker 服务器地址列表(Broker可能是Cluster模式),然后根据负载均衡算法从列表中选择1台Broker ,建立连接通道,进行消息发送。
- 消费者在订阅某个topic的消息之前从 NamerServer 获取 Broker 服务器地址列表(Broker可能是Cluster模式),包括关联的全部Topic队列信息。进而获取当前订阅 Topic 存在哪些 Broker 上,然后直接跟 Broker 建立连接通道,开始消费数据。
- 生产者和消费者默认每30s 从 NamerServer 获取 Broker 服务器地址列表,以及关联的所有Topic队列信息,更新到Client本地。
3 总结
- Topic 主要是为了将消息进行归类,同一个业务中消息繁复,我们将消息按照特性进行划分,相同类型的消息称为一个 Topic。
- 当业务不断膨胀的时候,需要对Broker进行集群化,每个Broker实例包含1个 Broker Master 和 至少 1个Broker Slave ,通过 Data Sync、Async 来进行数据同步,这样达到生产和消费分离。
- 使用 NameServer 来进行 Broker 注册和管理,接收来自 Broker 集群的注册请求,提供心跳机制,检测 Broker 是否存活。
- NameServer 也用来进行路由管理,来保证 producer生产的消息需要发送到哪个Broker中,comsumer又要去哪个Broker里面去取数据。
MQ系列3:RocketMQ 架构分析的更多相关文章
- Spark系列(四)整体架构分析
架构流程图 说明 Driver端流程说明(Standalone模式) 使用spark-submit提交Spark应用程序Application. 通过反射的方式创建和构造一个DriverActor进 ...
- Storm系列(十六)架构分析之Executor-Bolt
准备消息循环的数据 函数原型: 1 let[executor-sampler (mk-stats-sampler (:storm-conf executor-data))] 主要功能: 定义tupl ...
- Storm系列(十五)架构分析之Executor-Spout
Spout实现mk-threads接口用于创建与Executor对应的消息循环主函数. defmulti mk-threads executor-selector Mk-threads函数的主消息循环 ...
- Storm系列(十四)架构分析之Executor-输入和输出处理
Executor的数据 mk-executor-data函数用于定义Executor中含有的数据. Executor的输入处理 根据executor-id从Worker的:executor-recei ...
- Storm系列(十二)架构分析之Worker-心跳信息处理
Worker通过worker-data方法定义了一个包含很多共享数据的映射集合,Worker中很多方法都依赖它 mk-worker 功能: 创建对应的计时器.Executor.接收线程接收消息 方 ...
- MQ系列5:RocketMQ消息的发送模式
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 在之前的篇章中,我们学习了RocketMQ的原理, ...
- MQ系列4:NameServer 原理解析
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 1 关于NameServer 上一节的 MQ系列3:RocketMQ 架构分析,我们大致介绍了 ...
- MQ系列6:消息的消费
MQ系列1:消息中间件执行原理 MQ系列2:消息中间件的技术选型 MQ系列3:RocketMQ 架构分析 MQ系列4:NameServer 原理解析 MQ系列5:RocketMQ消息的发送模式 在之前 ...
- apache kafka系列之性能优化架构分析
apache kafka中国社区QQ群:162272557 Apache kafka性能优化架构分析 应用程序优化:数据压缩 watermark/2/text/aHR0cDovL2Jsb2cuY3Nk ...
随机推荐
- Scalable Multi-Party Private Set-Intersection-解读
本文记录阅读该paper的笔记. 摘要 本文给出两种MPSI协议,采用的是星型拓扑结构,即有一个leader,需要和其他参与者交互.优点是并非所有各方都必须同时在线: (1)能抗半诚实攻击 通信复杂度 ...
- nginx 部署前端资源的最佳方案
前言 最近刚来一个运维小伙伴,做线上环境的部署的时候,前端更新资源后,总是需要清缓存才能看到个更新后的结果.客户那边也反馈更新了功能,看不到. 方案 前端小伙伴应该都知道浏览器的缓存策略,协商缓存和强 ...
- 如何在Vue项目中,通过点击DOM自动定位VScode中的代码行?
作者:vivo 互联网大前端团队- Youchen 一.背景 现在大型的 Vue项目基本上都是多人协作开发,并且随着版本的迭代,Vue 项目中的组件数也会越来越多,如果此时让你负责不熟悉的页面功能开发 ...
- 记一次ms17-010复现过程
最近碰到业务需要使用msf,以前了解过,后面都忘记了.这次干脆写下来,省的每次去找别人写的. 首先是使用nmap探测端口 nmap -O -sV 192.168.153.130 --script=vu ...
- 引入gitlab仓库代码到npm包的教程
背景介绍 随着人类地发展,社会地进步,计算机技术地更新迭代,每一片码海里都有它宝贵的财富,每一座码山里都有着各自的秘密.怎么守住财富,隐藏一些秘密,成了一些开发人员所关心的事情. 需求分析 简单地说, ...
- 使用Karmada实现Helm应用的跨集群部署
摘要:借助Karmada原生API的支持能力,Karmada可以借助Flux轻松实现Helm应用的跨集群部署. 本文分享自华为云社区< 使用Karmada实现Helm应用的跨集群部署[云原生开源 ...
- Sentinel-流量防卫兵
1.背景 1.1 简介 Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性. Sentinel 具有以下特征 丰富的应用场景:Sentinel 承接了阿里巴 ...
- 岭回归和LASSO
0.对于正则罚项的理解 1.岭回归(L2 ridge regression ) 是一种专用于共线性数据分析的有偏估计回归方法,实质上是一种改良的最小二乘估计法,通过放弃最小二乘法的无偏性,以损失部分信 ...
- 小白对Java的呐喊
1 public class Hello{ 2 public static void main(string[] args){ 3 System.out.print("hello world ...
- 阿里 Maven仓库
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...