消息队列--必须掌握的两个基础模式

news2024/11/26 21:34:00

目录

  • 队列模式
    • 有什么设计的问题?
  • 发布订阅模式
    • 生产者如何确认消息发往哪个队列?
  • 总结

队列模式

我们都知道队列是一种数据结构吗,它的特性是先进先出,就跟我们平时在食堂打饭排队一样,排在前面的同学打完饭了就走了,后面的同学顶上去打饭。

在这里插入图片描述

而消息队列,直观来看就是信息排成了队列,被消费了,这个消息就出队了,后续的消息顶上。

在这里插入图片描述

一开始的消息队列就是这样设计的,生产者发送的信息被排成队列,然后消费者们竞争消费队列上的信息。

为什么称之为竞争?

按照队列的特性,消费被消费了就等于出队,即从队列上被移除了,那么每条信息只会被一个消费者消费,因此消费者之间是竞争关系。

在这里插入图片描述

这个特性很符合初期的需求,一个消息被消费了,自然就应该被移除,不会影响后续的消息被消费。

有什么设计的问题?

刚刚讲的就是队列模式。这样的设计在早期没问题,但是随着互联网演进,系统的复杂性不断提升,随之而来的需求也更加繁琐。

就像一个消息可能有很多消费者都感兴趣,但是他们之间又不是竞争消费的关系,即这些消费者都想消费所有的消息。

在这里插入图片描述

这个时候队列模式是不是就不合适了?因为队列的设计是消息被消费了就出队,而出队了如何再被别的消费者消费呢?

很自然我们会想到把消息复制成多份,也就是多队列。

这样一条信息被冗余到多个队列中,每个队列都包含全量的信息,这就满足了这些不是竞争关系的消费者们的需求。

在这里插入图片描述

但这样的方式也有问题:对存储不是特别很友好了,因为随着消费者们的增加,队列会越来越多,冗余的消息也会越来越多。

于是逐步推进,出现了发布-订阅模式。

发布订阅模式

生产者发布消息,消费者订阅消息,订阅的依据是什么?就是我们上篇文章提到的Topic(主题)。

生产者发布消息,消费者订阅消息,订阅的依据是啥?就是我上篇文章提到的Topic(主题)。

发布-订阅模式想要实现的功能是:比如我往Topic-LOL这个主题发布消息,那么订阅了这个主题的消费者都能收到这个消息,我往Topic-DOTA这个主题发布消息,那么订阅了DOTA主题的消费者都能收到DOTA相关的消息。

从概念上,发布-订阅模型完美契合一个消息可以被多个消费者同时消费的需求。

那具体是如何实现的呢?

这里就需要引入**消息位置(offset)**的概念,这个既念你可以类比理解为数组的下标。

我们的述求是消息可以被多个消费者消费,那么只需维护每个消费者已经消费到的位置,每当消费者消费一条消息,消费位置就+1,然后消费者根据记录的消息位置去消费对应的数据即可。

就跟遍历数组一样,下标+1来访问后面的数据。这样就能满足不同消费者消费同一条消息,且不影响他们之间的消费进度的需求。如下图:

在这里插入图片描述

当小火龙消费完Topic-LOL三条消息后,将位置+1,也就可以顺利访问第四条消息了。

假如后来又来了一个妙蛙种子,我们当然也不需要再复制消息了,只需要多一个妙蛙种子的消息位置记录即可。

这样即使消费者很多,对存储的也没什么影响。初步来看问题得以解决,

但是还记得我们上篇文章提到的消费者组的概念吗?就杰尼龟一个人忙不过来所以组成了自己的小团队,一个消费者单独消费Topc的速度有限,于是乎形成了消费组的概念,消费组内的消费者共同分担消费Topc中信息。

那么问题来了。

同一个消费组内的消费者如何消费消息呢?让他们竞争同一个消费位置吗?那岂不是需要等上一个消费者消费完了,组内其他消费者才能消费下一条消息?

这样效率就很低了。

所以这里还需要引入一个概念,在RokcetMQ中叫队列(这个和数据结构的概念要区分),在Kafka中叫分区。

在这里插入图片描述

可以看到,发往一个Toc的消息,实际上不是在一个队列里,而是分布在多个队列中。这样属于一个消费组的消费者们可以专门负责主题里面的一个队列

然后我们消费点位的记录维度就变成了Topc-消费组-队列,比如现在一共有两个主题,分别是 Topic-LOL、Topic-DOTA,每个主题都有两个队列(分区)。

在这里插入图片描述

这样一来,我们就完美解决了之前队列模式一个消息只能被一个消费者消费的问题,也实现了消费组之间的消费互不影响,且消费组内多个消费者之间的消费也互不影响。

这个方案非常灵活,加队列同时加消费者的处理方式就是消息堆积的一个解决办法之一(面试常问,别急后续我会专门出文章讲解这一块内容)

至此,我们就清晰了企业级消息队列实现的发布-订阅模式的核心原理:即Topic下分队列(分区),然后维护每个消费组在每个Topic下每个队列的消息位置,以消息位置(offset)来控制消息消费的进度。

消息位置的灵活性不仅仅能区分不同消费组或者说消费者们的消费进度,还能实现重复消费或者跳过部分消息不消费的功能。比如小火龙-1已经消费到Topic-LOL-队列1-20,即第20条消息,但是小火龙-1不小心把之前关于 Topc-LOL的消费得到的结果数据弄丢了,如果按照队列模式那就找不到消息了,因为消息已经出队了没了。而在发布-订阅模式中,我们仅需把这个消息位置变更成Topic-LOL-队列1-0,这样又可以让小火龙-1重新消费,只需要简单地改一条数据就能实现这样功能。

生产者如何确认消息发往哪个队列?

现在再让我们将视线从消费者转到生产者。

一个Topic里面有多个队列,那么生产者怎么知道要发往哪个队列?

一个很简单的办法就是轮询,比如生产者-A,要往Topic-LOL发送信息,那么第一条发给队列-1,第二条发给队列-2,第三条发给队列-3,第四条再发给队列-1如此反复即可。

这样每个队列的信息量会很平均,对应的消费者的工作量也很均衡。

当然也可以指定发往某个队列,比如有关永劫无间的信息都发往队列-1,有关英雄联盟的消息都发往队列-2,有关双人成行的消息都发往队列-3.

有关于这块的内容,我们后续再详谈,现在大概了解即可。

总结

今天我们介绍了消息队列的两个消息模式,分别是:队列模式和发布-订阅模式。

后续我们会介绍常见的MQ中间件的特性,现在打好基础即可。

希望读者着重掌握发布-订阅模式,这对后续进阶的消息负载均衡,顺序消息等很关键。

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

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

相关文章

数据结构——排序算法——希尔排序

希尔排序本质上是对插入排序的一种优化,它利用了插入排序的简单,又克服了插入排序每次只交换相邻两个元素的缺点。它的基本思想是: 1.将待排序数组按照一定的间隔分为多个子数组,每组分别进行插入排序。这里按照间隔分组指的不是…

Optional<T>

java中的 Optional类&#xff1a; //Optional用于处理可能为空的值的容器类&#xff0c;目的为了解决空指针问题 public final class Optional<T>{//Return true if there is a value present, otherwise false.//Returns:true if there is a value present, otherwise…

Spring Boot @Value读不到Nacos配置中心的值。(properties配置文件)

读不到配置中心的值&#xff0c; 配置中心的配置文件名字&#xff08;Data ID的值&#xff09;要以.properties结尾。 如果是yaml&#xff0c;就以yaml命名。

大数据Flink(七十八):SQL 的水印操作(Watermark)

文章目录 SQL 的水印操作(Watermark) 一、为什么要有 WaterMark

计算由于海洋温度和盐度变化产生的比容海平面变化

近些年由于全球气候变暖&#xff0c;全球的海平面不断上升。目前的研究显示&#xff0c;造成海平面变化的原因主要有两个&#xff1a;一个是由于陆地质量的流入&#xff08;比如两级冰川的融化&#xff0c;冰雪以径流的形式汇入海洋&#xff0c;总体上使得海洋的总质量产生变化…

Redis新篇一:认识Redis

首先&#xff0c;很抱歉小伙伴们&#xff0c;前段时间一直都没有更新&#xff0c;我很抱歉&#xff0c;现在开始持续更新Redis相关内容啦&#xff01;有需要的小伙伴们可以持续关注一下小博主的新篇哦~ 希望对你们有帮助&#xff01; 作者&#xff1a;爱撸猫的程序员 博客地址…

<C++> 基于SSE实现图像二值化

基于SSE实现图像二值化 SSE介绍及使用可见&#xff1a;https://blog.csdn.net/thisiszdy/article/details/132512686 本文使用SSE指令集来实现图像二值化算法&#xff0c;同时对比OpenCV二值化算子及for循环求解二值化的效果及性能。 // opencvTest.cpp : 此文件包含 "m…

2011-2022年北大法宝省市县环保行政处罚数据

2011-2022年北大法宝省市县环保行政处罚数据 1、时间&#xff1a;2011-2022年 2、范围&#xff1a;全国各省份、各城市、各区县 3、来源&#xff1a;北大法宝 4、数据指标&#xff1a;地区代码、地区名称、地区等级、所属省份、所属城市、处罚年份、主题分类、案件数目 5、…

如何使用谷歌浏览器连接linux服务器SSH服务

环境&#xff1a; 谷歌浏览器 版本 116.0.5845.141&#xff08;正式版本&#xff09; &#xff08;64 位&#xff09; Win10 专业版 安全外壳 (SSH)v.0.58 问题描述&#xff1a; 如何使用谷歌浏览器连接linux服务器SSH服务 解决方案&#xff1a; 1.找了有台安装好了这个插…

数据结构——排序算法——堆排序

堆排序过程如下&#xff1a; 1.用数列构建出一个大顶堆&#xff0c;取出堆顶的数字&#xff1b; 2.调整剩余的数字&#xff0c;构建出新的大顶堆&#xff0c;再次取出堆顶的数字&#xff1b; 3.循环往复&#xff0c;完成整个排序。 构建大顶堆有两种方式&#xff1a; 1.从 0 开…

2023更新:多功能短视频去水印工具微信小程序源码,带流量主功能(教程含源码)

简介&#xff1a; 这是一个自带去水印接口的多功能小程序&#xff0c;支持各大平台短视频去水印&#xff0c;保存封面、图集、标题等等&#xff0c;还可以本地图片去水印&#xff0c;图片拼接&#xff0c;九宫格切图&#xff0c;修改视频的MD5等等。当然&#xff0c;也支持流量…

LeetCode算法心得——和为k的子数组(前缀和+HashMap)

大家好&#xff0c;我是晴天学长&#xff0c;这是一个很重要的前缀和hash运用的题&#xff0c;为后面很多的题打基础&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。 1) .和为k的子数组 2) .算法思路 和为k的子数组 1.首先是前缀和 2.根据关系 s【…

Ceph入门到精通-S3 基准测试工具warp使用入门

S3 基准测试工具。 下载 下载适用于各种平台的二进制版本。 配置 可以使用命令行参数或环境变量配置 Warp。 可以使用 、 在命令行上指定要使用的 S3 服务器&#xff0c;也可以选择指定 TLS 和自定义区域。--host--access-key--secret-key--tls--region 也可以使用 、、 和…

22.Xaml TabControl 控件--->选项卡控件

1.运行效果 2.运行源码 a.Xaml源码 <Window x:Class="testView.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.mic…

计算机组成原理--数据表示

目录 1、机器数及特点 1.1 机器内的数据表示 1.1.1.原码 1.1.2. 反码 1.1.3. 补码 1.2 常见机器数的特点 2、定点数与浮点数据表示 2.1 定点数据表示 2.2 浮点数据表示 2.3 补充&#xff1a;小数的二进制表示 3、数据校验的基本原理 3.1 必要性&#xff1a; 3.2 基…

编程小白的自学笔记十四(python办公自动化创建、复制、移动文件和文件夹)

系列文章目录 编程小白的自学笔记十三&#xff08;python办公自动化读写文件&#xff09; 编程小白的自学笔记十二&#xff08;python爬虫入门四Selenium的使用实例二&#xff09; 编程小白的自学笔记十一&#xff08;python爬虫入门三Selenium的使用实例详解&#xff09; …

X86_64函数调用汇编程序分(2)

X86_64函数调用汇编程序分&#xff08;2&#xff09; 1 X86_64寄存器使用标准2 leaveq和retq指令2.1 leaveq2.2 retq 3 执行leaveq和retq之后栈的结构3.1 执行leaveq之后栈的结构3.1.1 test_fun_b函数执行leaveq之前的栈结构示意图3.1.2 test_fun_b函数执行leaveq之后的栈结构示…

MySQL使用Xtrabackup备份到AWS存储桶

1.安装Xtrabackup cd /tmp wget https://downloads.percona.com/downloads/Percona-XtraBackup-8.0/Percona-XtraBackup-8.0.33-28/binary/redhat/7/x86_64/percona-xtrabackup-80-8.0.33-28.1.el7.x86_64.rpm yum -y localinstall percona-xtrabackup-80-8.0.33-28.1.el7.x86…

Markdown 字体变红色,2种办法

老读者都知道王哥是 10 年 markdown 专家&#xff0c;今天教大家如何搞定字体颜色通用技巧 文章目录 方案一效果 方案二效果 颜色参考表 方案一 HEML 代码&#xff1a; <font colorred> 学技术&#xff0c;到 JavaPub </font>或者 <font colorFF0000> 学技术…

OpenCV之图片修复(inpaint)

图片修复基本原理&#xff1a; 我们自己标定噪声的特征&#xff0c;然后根据噪声周围区域的颜色特征修复噪声所在的区域。通俗一点就是用邻近的像素替换那些坏标记&#xff0c;使其看起来像是邻居。 如下图&#xff0c;需要将白色框框去掉&#xff1a; 标定噪声特征 先分析白…