当前位置: 首页 > news >正文

第二章 RocketMQ 的安装与启动

1、基本概念

1、消息(Message)

消息是指,消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题。

2、主题(Topic)

Topic 表示一类信息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是 RocketMQ 进行消息订阅的基本单位。topic:message 1:n        message:topic 1:1

一个生产者可以同时发送多种 Topic 的消息;而一个消费者只对某种特定的 Topic 感兴趣,即只可以订阅和消费一种 Topic 的消息。producer:topic 1:n        consum:topic 1:1

3、标签(Tag)

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

Topic 是消息的一级分类,Tag 是消息的二级分类。

  • Topic:货物
    • tag = 上海
    • tag = 江苏
    • tag = 浙江

------消费者------

  • topic = 货物 tag = 上海
  • topic = 货物 tag = 上海|浙江
  • topic = 货物 tag = *

4、队列(Queue)

存储消息的物理实体。一个 Topic 中可以包含多个 Queue,每个 Queue 中存放的就是该 Topic 的消息。一个 Topic 的 Queue 也被称为一个 Topic 中消息的分区(Partition)。

一个 Topic 的 Queue 中的消息只能被一个消费组中的一个消费者消费。一个 Queue 中的消息不允许同一个消费组中的多个消费者同时消费。

在学习参考其他相关资料时,还会看到一个概念:分片(Sharding)。分片不同于分区。在 RocketMQ 中,分片指的是存放相应 Topic 的 Broker。每个分片中会创建出相应数量的分区,即 Queue,每个 Queue 的大小都是相同的。

 5、消息标识(MessageId/Key)

RocketMQ 中每个消息拥有唯一的 MessageId,且可以携带具有业务标识的 Key,以方便对消息的查询。不过需要注意的是,MessageId 有两个:在生产者 send() 消息时会自动生成一个 MessageId(msgId),当消息到达 Broker 后,Broker 也会自动生成一个 MessageId(offsetMsgId)。msgId、offsetMsgId 与 key 都称为消息标识。

  • msgId:由 producer 端生成,其生成规则为:producerIp + 进程pid + MessageClientIDSetter 类的 ClassLoader 的 hashCode + 当前时间 + AutomicInteger 自增计数器
  • offsetMsgId:由 broker 端生成,其生成规则为:brokerIp + 物理分区的 offset(Queue 中的偏移量)
  • key:由用户指定的业务相关的唯一标识

2、系统架构

RocketMQ 架构上主要分为四部分构成:

1、Producer

消息生产者,负责生产消息。Producer 通过 MQ 的负载均衡模块选择相应的 Broker 集群队列进行消息投递,投递的过程支持快速失败并且低延迟。

例如,业务系统产生的日志写入到 MQ 的过程,就是消息生产的过程

再如,电商平台中用户提交的秒杀请求写入到 MQ 的过程,就是消息生产的过程

RocketMQ 中的消息生产者都是以生产者组(Producer Group)的形式出现的。生产者组是同一类生产者的集合,这类 Producer 发送相同 Topic 类型的消息。一个生产者组可以同时发送多个主题的消息。

2、Consumer

消息消费者,负责消费消息。一个消息消费者会从 Broker 服务器中获取到消息,并对消息进行相关业务处理。

例如,QoS 系统从 MQ 中读取日志,并对日志进行解析处理的过程就是消息消费的过程。

再如,电商平台的业务系统从 MQ 中读取到秒杀请求,并对请求进行处理的过程就是消息消费的过程。

RocketMQ 中的消息消费者都是以消费者组(Consumer Group)的形式出现的。消费者组是同一类消费者的集合,这类 Consumer 消费的是同一个 Topic 类型的消息。消费者组使得在消息消费方面,实现负载均衡(将一个 Topic 中的不同的 Queue 平均分配给同一个 Consumer Group 的不同的 Consumer,注意,并不是将消息负载均衡)和容错(一个 Consumer 挂了,该 Consumer Group 中的其它 Consumer 可以接着消费原 Consumer 消费的 Queue)的目标变得非常容易。

消费者组中 Consumer 的数量应该小于等于订阅 Topic 的 Queue 数量。如果超出 Queue 数量,则多出的 Consumer 将不能消费消息。

不过,一个 Topic 类型的消息可以被多个消费者组同时消费。 

注意:

  • 消费者组只能消费一个 Topic 的消息,不能同时消费多个 Topic 消息
  • 一个消费者组中的消费者必须订阅完全相同的 Topic

3、Name Server

功能介绍

NameServer 是一个 Broker 与 Topic 路由的注册中心,支持 Broker 的动态注册与发现。

RocketMQ 的思想来自于 Kafka,而 Kafka 是依赖了 Zookeeper 的。所以,在 RocketMQ 的早期版本,即在 MetaQ v1.0 与 v2.0 版本中,也是依赖于 Zookeeper 的。从 MetaQ v3.0,即 RocketMQ 开始去掉了 Zookeeper 依赖,使用了自己的 NameServer。

主要包括两个功能:

  • Broker 管理:接收 Broker 集群的注册信息并且保存下来作为路由信息的基本数据;提供心跳检测机制,检测 Broker 是否还存活。
  • 路由信息管理:每个 NameServer 中都保存着 Broker 集群的整个路由信息和用于客户端查询的队列信息。Producer 和 Consumer 通过 NameServer 可以获取整个 Broker 集群的路由信息,从而进行消息的投递和消费。

路由注册

NameServer 通常也是以集群的方式部署,不过,NameServer 是无状态的,即 NameServer 集群中的各个节点间是无差异的,各节点间相互不进行信息通讯。那各节点中的数据是如何进行数据同步的呢?在 Broker 节点启动时,轮询 NameServer 列表,与每个 NameServer 节点建立长连接,发起注册请求。在 NameServer 内部维护着一个 Broker 列表,用来动态存储 Broker 的信息。

注意,这是与其它像 zk、Eureka、Nacos 等注册中心不同的地方。

这种 NameServer 的无状态方式,有什么优缺点:

优点:NameServer 集群搭建简单,扩容简单。

缺点:对于 Broker,必须明确指出所有 NameServer 地址。否则未指出的将不会去注册。也正是因为如此,NameServer 并不能随便扩容。因为,若 Broker 不重新配置,新增的 NameServer 对于 Broker 来说是不可见的,其不会向这个 NameServer 进行注册。

Broker 节点为了证明自己是活着的,为了维护与 NameServer 间的长连接,会将最新的信息以心跳包的方式上报给 NameServer,每 30 秒发送一次心跳。心跳包中包含 BrokerId、Broker 地址(IP + Port)、Broker 名称、Broker 所属集群名称等等。NameServer 在接收到心跳包后,会更新心跳时间戳,记录这个 Broker 的最新存活时间。

路由剔除

由于 Broker 关机、宕机或网络抖动等原因,NameServer 没有收到 Broker 的心跳,NameServer 可能会将其从 Broker 列表中剔除。

NameServer 中有一个定时任务,每隔 10 秒就会扫描一次 Broker 表,查看每一个 Broker 的最新心跳时间戳距离当前时间是否超过 120 秒,如果超过,则会判定 Broker 失效,然后将其从 Broker 列表中剔除。

扩展:对于 RocketMQ 日常运维工作,例如 Broker 升级,需要停掉 Broker 的工作。OP 需要怎么做?

OP 需要将 Broker 的读写权限禁掉。一旦 client(Consumer 或 Producer)向 broker 发送请求,都会收到 broker 的 NO_PERMISSION 响应,然后 client 会进行对其它 Broker 的重试。

当 OP 观察到这个

相关文章:

  • openGauss学习笔记-212 openGauss 数据库运维-日志参考
  • php工厂模式
  • 网络协议与攻击模拟_11DHCP欺骗防护
  • 服务器常遇的响应状态码
  • Linux 驱动开发基础知识—— 具体单板的 LED 驱动程序(五)
  • 代码随想录算法训练营day 23|第六章 二叉树part09
  • Qt 5.9.4 转 Qt 6.6.1 遇到的问题总结(三)
  • 嵌入式Linux学习DAY18---IO编程
  • 正则表达式可视化工具regex-vis
  • 【Android】二级分类双列表联动Demo
  • 【Git】03 图形化工具
  • <网络安全>《15 移动安全管理系统》
  • Android 中的卡顿优化
  • 回归预测 | Matlab实现POA-CNN-LSTM-Attention鹈鹕算法优化卷积长短期记忆网络注意力多变量回归预测(SE注意力机制)
  • OceanBase 4.2.2 GA 发布,全新特性快速预览!
  • 《深入 React 技术栈》
  • 【个人向】《HTTP图解》阅后小结
  • 2019年如何成为全栈工程师?
  • 230. Kth Smallest Element in a BST
  • CSS 三角实现
  • css的样式优先级
  • Effective Java 笔记(一)
  • emacs初体验
  • IDEA 插件开发入门教程
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • Mocha测试初探
  • mongo索引构建
  • opencv python Meanshift 和 Camshift
  • windows下如何用phpstorm同步测试服务器
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 简单数学运算程序(不定期更新)
  • 来,膜拜下android roadmap,强大的执行力
  • 码农张的Bug人生 - 初来乍到
  • 如何邀请好友注册您的网站(模拟百度网盘)
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (论文阅读40-45)图像描述1
  • (十) 初识 Docker file
  • (十一)JAVA springboot ssm b2b2c多用户商城系统源码:服务网关Zuul高级篇
  • (转)Android学习笔记 --- android任务栈和启动模式
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .NET/C# 使窗口永不获得焦点
  • .NET命令行(CLI)常用命令
  • /*在DataTable中更新、删除数据*/
  • @WebServiceClient注解,wsdlLocation 可配置
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [20150904]exp slow.txt
  • [2018][note]用于超快偏振开关和动态光束分裂的all-optical有源THz超表——
  • [AIGC] Kong:一个强大的 API 网关和服务平台
  • [BZOJ 3531][Sdoi2014]旅行(树链剖分+线段树)
  • [c#基础]DataTable的Select方法