消息队列的基本概念

news2024/11/26 17:31:00

每种消息队列都有自己的一套消息模型,像队列(Queue)、主题(Topic)或是分区(Partition)这些名词概念,在每个消息队列模型中都会涉及一些,含义还不太一样。

为什么出现这种情况呢?因为没有标准。曾经,也是有一些国际组织尝试制定过消息相关的标准,比如早期的 JMS 和 AMQP。但让人无奈的是,标准的进化跟不上消息队列的演进速度,这些标准实际上已经被废弃了。

主题和队列有什么区别

最初的消息队列,就是一个严格意义上的队列。在计算机领域,“队列(Queue)”是一种数据结构,有完整而严格的定义。在维基百科中,队列的定义是这样的:

队列是先进先出(FIFO, First-In-First-Out)的线性表(Linear List)。在具体应用中通常用链表或者数组来实现。队列只允许在后端(称为 rear)进行插入操作,在前端(称为 front)进行删除操作。

这个定义里面包含几个关键点,第一个是先进先出,这里面隐含着的一个要求是,在消息入队出队过程中,需要保证这些消息严格有序,按照什么顺序写进队列,必须按照同样的顺序从队列中读出来。不过,队列是没有“读”这个操作的,“读”就是出队,也就是从队列中“删除”这条消息。

**早期的消息队列,就是按照“队列”的数据结构来设计的。**我们一起看下这个图,生产者(Producer)发消息就是入队操作,消费者(Consumer)收消息就是出队也就是删除操作,服务端存放消息的容器自然就称为“队列”。

image-20230613163555583

这里就会有一个问题,如果多个生产者汪队列里面发送消息,那么消息的顺序就是生产者发送消息的自然顺序。如果有多个消费者接受同一个队列的消息,实际上每个消费者是竞争关系,他们都只能接收到一部分的消息。当然这种情况是允许的。

如果我们需要每个消费者都接受到每一条消息,全量的消息,这个时候但各队列就满足不了需求,我们可以给每个消费者都创建一个队列用作接收消息。但是这种做法不仅复杂而且维护起来十分麻烦。

为了解决这个问题就演化出了另一种消息模型:“发布 - 订阅模型(Publish-Subscribe Pattern)

image-20230613164058925

在这种模型中,消息的发送方称之为发布者(Publisher),消息的接收方称之为(Subscriber),服务端存放消息的容器称之为主题(Topic)发布者将消息发送到主题中,订阅者在接收消息之前需要先“订阅主题”。“订阅”在这里既是一个动作,同时还可以认为是主题在消费时的一个逻辑副本,每份订阅中,订阅者都可以接收到主题的所有消息。

在消息领域的历史上很长的一段时间,队列模式和发布 - 订阅模式是并存的,有些消息队列同时支持这两种消息模型,比如 ActiveMQ。我们仔细对比一下这两种模型,生产者就是发布者,消费者就是订阅者,队列就是主题,并没有本质的区别。它们最大的区别其实就是,一份消息数据能不能被消费多次的问题。

RabbitMQ 的消息模型

在 RabbitMQ 中,Exchange 位于生产者和队列之间,生产者并不关心将消息发送给哪个队列,而是将消息发送给 Exchange,由 Exchange 上配置的策略来决定将消息投递到哪些队列中。

image-20230613164452912

同一份消息如果需要被多个消费者来消费,需要配置 Exchange 将消息发送到多个队列,每个队列中都存放一份完整的消息数据,可以为一个消费者提供消费服务。

RocketMQ 的消息模型

​ RocketMQ 使用的消息模型是标准的发布 - 订阅模型,在 RocketMQ 的术语表中,生产者、消费者和主题与我在上面讲的发布 - 订阅模型中的概念是完全一样的。

但是,在 RocketMQ 也有队列(Queue)这个概念,并且队列在 RocketMQ 中是一个非常重要的概念,那队列在 RocketMQ 中的作用是什么呢?这就要从消息队列的消费机制说起。

​ 几乎所有的消息队列产品都使用一种非常朴素的“请求 - 确认”机制,确保消息不会在传递过程中由于网络或服务器故障丢失。

​ 我们都知道有消息确认机制,也就是确保这条消息被消费了,这条消息才会被删除。这个机制很好地保证了消息传递过程中的可靠性。但是同时也会产生这样一个问题,在某一条消息被成功消费之前,下一条消息是不能被消费的,否则就会出现消息空洞,违背了有序性这个原则。

​ 也就是说,每个主题在任意时刻,至多只能有一个消费者实例在进行消费,那就没法通过水平扩展消费者的数量来提升消费端总体的消费性能。为了解决这个问题,RocketMQ 在主题下面增加了队列的概念。

​ **每个主题包含多个队列,通过多个队列来实现多实例并行生产和消费。**需要注意的是,RocketMQ 只在队列上保证消息的有序性,主题层面是无法保证消息的严格顺序的。

​ 在 Topic 的消费过程中,由于消息需要被不同的组进行多次消费,所以消费完的消息并不会立即被删除,这就需要 RocketMQ 为每个消费组在每个队列上维护一个消费位置(Consumer Offset),这个位置之前的消息都被消费过,之后的消息都没有被消费过,每成功消费一条消息,消费位置就加一。这个消费位置是非常重要的概念,我们在使用消息队列的时候,丢消息的原因大多是由于消费位置处理不当导致的

image-20230615143537195

Kafka 的消息模型

片转存中…(img-Qg4afy0b-1686812023938)]

Kafka 的消息模型

​ Kafka 的消息模型和 RocketMQ 是完全一样的,我刚刚讲的所有 RocketMQ 中对应的概念,和生产消费过程中的确认机制,都完全适用于 Kafka。唯一的区别是,在 Kafka 中,队列这个概念的名称不一样,Kafka 中对应的名称是“分区(Partition)”,含义和功能是没有任何区别的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/649694.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.8C++流提取运算符重载

C流提取运算符重载 在 C中,流提取运算符(>>)是用于从流中提取数据的运算符。 C中的流提取运算符可以被重载,使得程序员可以自定义输入对象的方式,更方便地输入自定义的数据类型,也可以使得输入更加…

阿里云轻量应用服务器和云服务器ECS区别(终于懂了)

阿里云服务器ECS和轻量应用服务器有什么区别?云服务器ECS是明星级云服务器,轻量应用服务器可以理解为简化版的云服务器ECS,轻量适用于单机应用,云服务器ECS适用于集群类高可用高容灾应用,阿里云百科来详细说下阿里云轻…

dbGet 快速学习教程

dbGet是innovus/encounter工具自带的"database access command"命令中的一部分,它几乎可以用来获取设计相关的一切信息。 输入dbGet 按[Tab]键,能看到三个选项,分别是head / top /selected。这三个选项所代表的意义如下: head --…

Vue3对于一个前端来讲意味着什么?

最近很多技术网站,讨论的最多的无非就是Vue3了,大多数都是Composition API和基于Proxy的原理分析。但是今天想着跟大家聊聊,Vue3对于一个低代码平台的前端更深层次意味着什么? 首先,Vue是前端三大主流框架之一&#xf…

python,如何设置定时执行python代码-windows本地

最近写了一个python小程序,希望能每天定时执行,但是又不想用jenkins这样的工具,后来发现windows本地就可以设置,而且很好用,具体步骤如下: 首先,需确保本地python代码已编写好,环境…

c++创建对象常见的坑

c创建对象常见的坑 创建对象的时候不要在对象名后面加空的圆括号,编译器误认为是声明函数。(如果没有构造函数、构造函数没有参数、构造函数的参数都有默认参数)在构造函数名后面加括号和参数不是调用构造函数,是创建匿名对象。以…

【有奖调研】HarmonyOS新物种,鸿蒙流量新阵地——元服务邀你来答题!

“聊技术无话不谈,一起来吹吹元服务!畅聊你对元服务的想法,说不定,你就能撬动元服务的爆发增长!” 元服务(即原子化服务)是华为“轻量化”服务的新物种,可提供全新的服务和交互方式…

人工智能(pytorch)搭建模型12-pytorch搭建BiGRU模型,利用正态分布数据训练该模型

大家好,我是微学AI,今天给大家介绍一下人工智能(pytorch)搭建模型12-pytorch搭建BiGRU模型,利用正态分布数据训练该模型。本文将介绍一种基于PyTorch的BiGRU模型应用项目。我们将首先解释BiGRU模型的原理,然后使用PyTorch搭建模型…

uniApp -- 学习笔记(vue3+ts)

uniApp学习笔记目录 一.关于界面节点信息 6月15 一.关于界面节点信息 6月15 uniApp官网介绍 (一) 个人理解是官网返回一个 SelectorQuery 对象实例。 并且可以在这个实例上使用 select 等方法选择节点,并使用 boundingClientRect 等方法选择…

使用 Sharesheet分享Android 应用链接

使用 Sharesheet分享Android 应用链接 使用 Sharesheet 进行丰富的链接共享 Android App Links 允许您的应用程序打开网页链接,而不是使用网络浏览器。处理这些深层链接已在我们的《深层链接入门课程》中介绍过。除了能够打开深层链接外,您的应用程序还…

《Lua程序设计》--学习8

编译,执行和错误 编译 可以认为dofile函数就是这样: loadfile函数从文件中加载Lua代码段,但它不会运行代码,只是编译代码,然乎将编译后的代码段作为一个函数返回 函数loadfile更灵活。在发生错误的情况中&#xff0…

100种思维模型之排列组合思维模型-78

说到模型,一般人会觉得特别难,会觉得是学霸级别的人才能做出来的高科技。 然实际上并不是! 西方人常说Model,模型在西方人眼里是一个非常常见的词。 查理芒格,多元思维模型倡导者和践行者,他说任何能够帮助…

Elasticsearch:实用 BM25 - 第 1 部分:分片如何影响 Elasticsearch 中的相关性评分

作者:Shane Connelly 背景 在 Elasticsearch 5.0 中,我们切换到 Okapi BM25 作为我们的默认相似度算法,这是用于对与查询相关的结果进行评分的算法。 在本博客中,我不会过多地介绍 BM25 与替代措施,但如果你想了解 B…

3天没睡吐血整理,性能测试瓶颈问题+分析,一篇概全...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 如何定位性能瓶颈…

白鲸优化算法优化VMD参数,并提取特征向量,以西储大学数据为例,附MATLAB代码

大家看到这篇文章,肯定会有疑问,难道本篇文章和上一篇文章不是一个意思嘛,这是来凑数的嘛……其实不然,如果各位读者仔细看,就会发现本篇文章和上一篇文章大有不同,这篇文章也是我一直以来想在上一篇文章基…

TALL论文笔记

TALL论文笔记 0.论文来源1摘要2引言3模型结构3.1视觉编码器3.2句子编码器3.3模态融合3.4时间定位回归网络 4训练4.1损失函数4.2采集训练样本 5 评估5.1数据集5.2评价指标5.3实验结果 0.论文来源 2017 TALL 1摘要 问题描述:通过语言来对未修剪视频中动作的时间定位…

【JVM】日志分析工具--gcviewer的使用

文章目录 gcviewer是什么?gcviewer的使用最后 gcviewer是什么? GCViewer是一个小工具,可以可视化Sun / Oracle、IBM、HP和BEA Java虚拟机生成的详细GC输出。它是在GNU LGPL下发布的自由软件。—官网翻译 gcviewer的使用 文章使用的配置 工具…

Dubbo面试题

Dubbo 基础知识为什么要用 Dubbo?Dubbo 是什么?Dubbo 的使用场景有哪些?Dubbo 核心功能有哪些? 架构设计Dubbo 服务器注册与发现的流程?Dubbo 的整体架构设计有哪些分层?Dubbo Monitor 实现原理? 分布式框…

一键部署通义千问预体验丨阿里云云原生 5 月动态

云原生月度动态 云原生是企业数字创新的最短路径。 《阿里云云原生每月动态》,从趋势热点、产品新功能、服务客户、开源与开发者动态等方面,为企业提供数字化的路径与指南。 本栏目每月更新。 01 趋势热点 🥇 Apache RocketMQ 入选可信开…

如何创建 GitHub 配置文件自述文件

背景 最近再搞GitHub Actions的东西。突然看到了 github推出的这项服务。就搞了一下。主要目的:装扮自己的GitHub主页。俗称装逼(小声) 步骤 创建一个与 GitHub 用户名同名(包括大小写)的新仓库。比如我的就是 创建…