MQ消息队列篇:三大MQ产品的必备面试种子题

MQ有什么用?

MQ(消息队列)是一种FIFO(先进先出)的数据结构,主要用于实现异步通信、削峰平谷和解耦等功能。它通过将生产者生成的消息发送到队列中,然后由消费者进行消费。这样,生产者和消费者之间就不存在直接的耦合关系。

其中,MQ的优势主要体现在以下几个方面:

  • 异步通信:由于存在MQ这个中间件,生产者将消息发送到队列后,可以立即返回,无需等待消费者处理完毕。这样可以提高系统的响应速度和并发能力。
  • 削峰平谷:当系统出现峰值请求时,MQ可以存储大量的请求消息,将峰值数据缓冲下来,然后由消费者按照自己的处理能力逐步消费。这样可以避免系统因突发流量而崩溃,提高系统的稳定性和可靠性。
  • 解耦功能:MQ可以将生产者和消费者两端分离开来,实现系统之间的解耦。尤其在跨语言的场景下,MQ可以轻松实现不同语言程序之间的通信,简化开发和维护的复杂性。

然而,引入MQ也存在一些劣势需要注意:

  • 高可用性要求:为了保证MQ的正常运行,需要对MQ进行高可用性的设计和部署。一旦MQ宕机,整个业务流程可能会受到影响,导致系统不可用。
  • 系统复杂性提高:引入MQ后,需要专门的人员进行维护和管理,并对MQ产品有深入的了解。同时,为了保证消息的不丢失和消费幂等性,还需要进行一些额外的工作。
  • 系统一致性问题:由于MQ是异步通信的方式,当一个业务生成后,如果需要两个系统之间的一致性,就需要保证两个系统都成功执行完成。否则,可能会出现数据不一致的情况。

综上所述,MQ在提供异步通信、削峰平谷和解耦等功能的同时,也需要注意高可用性、系统复杂性和系统一致性等问题。在使用MQ时,需要综合考虑这些因素,并进行适当的设计和调优。

如何进行产品选型

目前市场上有三大主流MQ产品供选择,它们分别是kafka、rabbitmq和rocketmq。

  • kafka的性能最快,效率最高,适用于处理日志分析、大数据分析等场景。然而,kafka存在数据丢失的风险,并且功能相对单一,不保证消息的可靠性。
  • rabbitmq保证了消息的可靠性,但无法处理大数据量的消息队列。一旦数据量增大,整个MQ服务器的性能将下降。因此,rabbitmq适用于小规模场景。
  • rocketmq吸取了kafka和rabbitmq的优点,几乎可以应用于各种场景。它既具有高效率又具有高可靠性。不过需要注意的是,开源版本的rocketmq可能不如商业版本稳定和可靠。

因此,在进行产品选型时,您需要综合考虑各个MQ产品的特点和适用场景。如果您需要处理大数据量的消息队列,可以考虑kafka或者商业版本的rocketmq。如果您对消息的可靠性要求较高,可以选择rabbitmq或者商业版本的rocketmq。

如何保证消息不丢失?

首先,我们要检查可能导致消息丢失的部分:

  • 生产者将消息发送到消息队列服务器;
  • 消息队列服务器宕机;
  • 消息队列服务器未将消息刷新到磁盘;
  • 消息队列将消息发送给消费者。

image

然后根据每一步开始分析如何保证消息不丢失;

RocketMQ独有的事务消息机制:

image

  1. 对于使用Kafka、RocketMQ、RabbitMQ的情况,它们都有消息确认机制。例如,消息只有在到达消息队列后才会返回确认信息。RocketMQ还有独有的事务消息机制,可以确认消息是否成功发送到消息队列服务器,并与相关业务进行关联。当消息队列服务器监听到生产者服务器未返回成功时,会持续回调生产者服务器,直到成功或超时。
  2. 如果消息队列服务器宕机,说明需要保证消息队列的高可用性。因此,必须使用集群环境。对于RocketMQ来说,它的节点分为主节点和从节点。一旦主节点宕机,从节点会立即启动,确保消息不丢失。但是主从同步是异步进行的,因此需要使用Dledger集群的两阶段提交来确保超过半数的机器同步成功后才能返回给生产者。对于RabbitMQ集群,普通集群是分散存储的,即所有集群的总和等于队列的总数,没有备份。这可能导致机器宕机后丢失部分数据,所以RabbitMQ有一个镜像集群,会主动在节点之间进行同步,解决了数据丢失的问题。至于Kafka,本身允许丢失数据的情况,因此不需要对Kafka进行大量的消息可靠性优化以减少效率问题。但它有一个ack确认机制。
  3. 对于RocketMQ,可以采用异步刷盘来确保效率,但如果要确保消息的可靠性,就需要使用同步刷盘机制,即损失一部分效率。对于RabbitMQ,可以设置队列持久化来确保消息刷盘。
  4. 当消息队列将消息投递给消费者时,消费者自己需要采取相应的策略。对于RocketMQ、RabbitMQ和Kafka,都应将消息的偏移量设置为手动提交,而不是自动提交。否则,如果某个消费者消费失败,该条消息将会丢失。

如何保证消息消费的幂等性?

为了保证消息消费的幂等性,我们可以采取以下策略。首先,在生产者端,我们需要为每条消息设置一个唯一的业务ID,确保消息的唯一性。这可以通过生成全局唯一的UUID或者使用分布式ID生成算法来实现。

然后,在消费端,我们可以利用一些中间件,比如Redis,来记录已经消费过的消息。这可以通过将消费过的消息的业务ID存储在Redis中来实现。在消费端处理消息之前,我们首先查询Redis,判断当前消息的业务ID是否已经存在。如果存在,说明该消息已经被消费过,可以直接忽略。如果不存在,说明该消息是新的,可以进行消费处理。

通过以上的策略,我们可以确保消息的幂等性,避免重复消费同一条消息。同时,使用中间件来记录已经消费过的消息,可以提高查询效率和降低存储空间的占用。这样,即使消费端出现异常或者重启,也能够保证消息的消费状态不会丢失,从而保证消息消费的可靠性。

如何保证消息的顺序

如何保证消息的顺序呢?虽然消息队列(MQ)本身可以保证局部的消息顺序,但并不能保证全局的消息顺序。这是因为在实际的系统中,为了提高可用性,通常会使用多个队列来存储消息,而无法将同一个业务的消息全部放入同一个队列中。因此,需要了解各种MQ的特性。

image

RocketMQ提供了有序队列的实现机制。它在主题(Topic)和队列(Queue)之间引入了一个Message Select机制,可以将同一个业务的消息发送到同一个队列中,从而保证消息的有序性。在消费端,如果你使用OrderMessageListen监听器来消费消息,它会在获取消息时,锁定一个队列,将该队列中的消息全部消费完,然后再获取下一个队列的消息。这样就能够保证消息的有序消费。

相比之下,RabbitMQ和Kafka并没有专门提供对消息顺序的支持。如果你确实需要保证消息的顺序,你可以将队列和消费者设置成一个,这样就能够保证有序性。但是这种方式效率较低,因此在实际应用中,需要仔细考虑是否真的需要使用有序性。

总之,在设计消息消费时,需要根据实际情况来选择是否需要保证消息的顺序。如果确实需要有序性,可以考虑使用RocketMQ等支持有序队列的MQ,或者将队列和消费者设置成一个。但需要注意,有序性可能会牺牲一定的性能,因此需要权衡利弊来做出决策。


如何保证消息的高效读写

传统文件复制方式: 需要对文件在内存中进行四次拷贝。

image

读写操作涉及到IO操作,而有关IO操作的优化,我们会想到零拷贝技术。在这方面,Kafka和RocketMQ都采用了零拷贝技术来优化文件读写性能。

零拷贝: 有两种方式, mmap和transfile

image

  • RocketMQ是一个分布式消息队列系统,它也使用了零拷贝技术来提高性能。RocketMQ通过使用DirectByteBuffer和FileChannel来实现零拷贝。
    在消息发送过程中,RocketMQ使用DirectByteBuffer作为消息缓冲区,并将消息直接写入到DirectByteBuffer中,而无需将数据从用户空间复制到内核缓冲区。然后,RocketMQ使用FileChannel将DirectByteBuffer中的数据直接写入到磁盘文件中,避免了数据的多次复制。

在消息消费过程中,RocketMQ同样使用DirectByteBuffer作为消息缓冲区,并使用FileChannel将磁盘文件中的数据直接读取到DirectByteBuffer中,而无需将数据从内核缓冲区复制到用户空间。

通过使用DirectByteBuffer和FileChannel,RocketMQ实现了零拷贝,从而提高了消息发送和消费的效率和性能。

  • 在读取和写入消息时,Kafka利用零拷贝技术来提高性能。具体来说,Kafka使用操作系统的"sendfile"系统调用,该调用允许直接将文件中的数据发送到网络套接字,而无需将数据从内核缓冲区复制到应用程序缓冲区。这样可以避免数据的多次复制,提高了数据传输的效率。
    此外,Kafka还使用了mmap(内存映射)技术,它可以将磁盘文件映射到内存中。通过使用mmap,Kafka可以避免将数据从磁盘读取到内核缓冲区,而是直接将文件映射到内存中,从而实现快速的数据读取和写入。

总的来说,Kafka通过使用"sendfile"系统调用和mmap技术来实现零拷贝,提高了数据的传输效率和性能。

使用MQ如何保证分布式事务的最终一致性?

分布式事务是一种要求只要有一个系统处理失败,整个事务都失败的机制。换句话说,要么所有的系统都成功地完成了它们的处理,要么所有的系统都失败了。这样可以确保数据的一致性。

最终一致性则是指在分布式系统中,允许存在中间状态,只要最终的状态保持一致即可,而不必要求强一致性。

在实现分布式事务和最终一致性时,有一些关键的优化策略:

  • 首先,生产者在完成业务处理后,必须确保消息被正确地投递到MQ服务器。这是为了防止消息丢失,因为如果消息丢失,就无法保证整个事务的一致性。
  • 其次,消费者需要保证消息的消费具有幂等性,即不会重复消费同一条消息。这可以通过在消费端记录已经消费过的消息的标识来实现。这样即使有重复的消息投递到消费者,消费者也可以正确地处理,而不会对业务数据造成重复影响。

让你设计一个MQ,你会如何设计?

首先,基于现有的MQ基础上进行定制化设计,不可放飞自我,避免漫无边际。可以站在现有MQ的巨人肩膀上,确保设计的东西不会出现漏洞。

  • 设计队列时,可以选择使用阻塞队列(blockingmq),将消息作为实体存放在队列中,包括消息体、消息ID等内容。同时,需要考虑单队列如何进行扩容和缩容的设计。
  • 为了提高分布式和效率,可以设计成多队列的形式。在多队列的情况下,引入一个中间角色来保存消息,并根据一定的策略将消息放入队列中,比如轮询等方式,以保证队列的均衡。此外,需要考虑生产者的消息确认机制,确保消息的可靠性。
  • 为了确保MQ的高可用性,可以设计MQ的高可用集群,保证系统在面对故障时能够自动切换,提供持续稳定的服务。
  • 在多消费者情况下,需要考虑如何从队列中获取消息,并进行消费。可以与队列形成多对一的关系,确保消息能够被所有消费者平均消费。
  • 为了进一步优化MQ的性能,可以考虑使用一些技术,比如顺序写、零拷贝等,提高数据传输的效率。
  • 最后,可以根据需求定制一些高级功能,如延迟队列、死信队列、有序队列等,以满足不同场景下的需求。

总结

MQ(Message Queue)是一种重要的技术,用于实现应用程序之间的异步通信,提高系统的可扩展性和可靠性。在选用MQ产品时,需要考虑以下几个方面:

  • 了解不同MQ产品的特点和适用场景,根据实际需求进行产品选型。
  • 为了保证消息的可靠传递,可以采用持久化机制,确保消息不会丢失。
  • 幂等性是保证消息消费的重要概念,可以通过唯一标识和消息状态进行判断。
  • 保证消息的顺序可以采用单一消费者或者分区有序的方式。
  • 高效读写可以通过批量发送和接收消息、消息压缩等方式进行优化。
  • 在分布式环境下,确保事务的最终一致性可以通过两阶段提交或者最大努力通知等方式实现。
  • 在设计一个自己的MQ时,需要考虑消息的存储和传输方式、高可用集群的设计、多消费者消费的问题以及性能优化和定制高级功能等方面。

通过对这些面试题的了解和思考,可以更好地理解MQ的作用和设计原则,为面试和实际应用提供参考。


我是努力的小雨,一名 Java 服务端码农,潜心研究着 AI 技术的奥秘。我热爱技术交流与分享,对开源社区充满热情。同时也是一位掘金优秀作者、腾讯云内容共创官、阿里云专家博主、华为云云享专家。

💡 我将不吝分享我在技术道路上的个人探索与经验,希望能为你的学习与成长带来一些启发与帮助。

🌟 欢迎关注努力的小雨!🌟

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(四)activit5.23.0修复跟踪高亮显示BUG

一、先看bug 在 (三)springboot2.7.6集成activit5.23.0之流程跟踪高亮显示 末尾就发现高亮显示与预期不一样,比如上面的任务2前面的箭头没有高亮显示。 二、分析原因 具体分析步骤省略了,主要是ProcessInstanceHighlightsResour…

【iOS】暑假第二周——网易云APP 仿写

目录 前言首页关于UINavigationBarAppearance “我的”账号夜间模式——多界面传值遇到的问题所用到的其他知识整理NSNotificationreloadData各种键盘模式 总结 前言 有了之前仿写ZARA的基础,本周我们仿写了网易云APP,在这里对多界面传值进行了首次应用—…

算力共享中神经网络切片和算力分配策略

目录 神经网络切片 按照算力的分布进行网络层数切片;就是算力越强,运算神经网络层数越多 神经网络切片和算力占比进行映射 算力分配策略 get_current_shard 神经网络切片 按照算力的分布进行网络层数切片;就是算力越强,运算神经网络层数越多 神经网络切片和算力占比进…

【MySQL】索引——索引的引入、认识磁盘、磁盘的组成、扇区、磁盘访问、磁盘和MySQL交互、索引的概念

文章目录 MySQL1. 索引的引入2. 认识磁盘2.1 磁盘的组成2.2 扇区2.3 磁盘访问 3. 磁盘和MySQL交互4. 索引的概念4.1 索引测试4.2 Page4.3 单页和多页情况 MySQL 1. 索引的引入 海量表在进行普通查询的时候,效率会非常的慢,但是索引可以解决这个问题。 -…

PHP中关于排名和显示的问题

🏆本文收录于《CSDN问答解惑-专业版》专栏,主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收…

RabbitMQ应用场景及特性

RabbitMQ是一款开源的消息队列中间件,拥有非常好用的管理控制面板,类似使用navicat一样,简便的操纵数据库。 应用场景 一、流量削峰 在一些并发量较高的场景下,比如秒杀活动,抢票等,同一时间访问量急剧增…

【Linux】shell命令与Linux权限的概念

目录 一、shell命令二、Linux权限的概念2.1 Linux权限的概念2.1.1 用户2.1.2 指令2.1.2.1 su指令2.1.2.2 sudo指令 2.2 Linux权限管理2.2.1 文件访问者的分类(人)2.2.2 文件类型和访问权限(事物属性)2.2.2.1 文件类型2.2.2.2 基本…

[240804] OpenTofu 1.8.0 发布,带来更友好的编码体验 | 生成式 AI 滥用现象分析

目录 OpenTofu 1.8.0 发布,带来更友好的编码体验生成式 AI 滥用现象分析 OpenTofu 1.8.0 发布,带来更友好的编码体验 OpenTofu 1.8.0 现已发布,主要功能包括: 变量和局部值的早期求值: 现在可以在模块源、后端配置和状态加密等更…

使用 1panel面板 部署 springboot 和 vue

代码仓库:还没弄 目录 网站介绍安装步骤1. 准备云服务器2. 准备域名(可跳过)3. 安装1panel面板4. 服务器开放端口5. 进入1panel面板6. 安装并启动软件(服务器和面板开放端口)7. 打包并上传项目7.1 打包 Java项目&#…

网页保护用户 小tips

在使用创建web开发的过程中,直接使用用户名url,容易造成用户信息的被攻击,例如对方直接访问 ../../.../username 的网页,可以窃取用户信息,然而把usename变成一堆乱码就安全的多 效果: 代码:…

想做抖音短视频,视频素材去哪里找啊?

各位抖音上的短视频创作者们,是否曾幻想过自己的作品能够在全网爆火,却常因为缺少那些能够让视频更加生动的素材而感到困扰?不用担心,今天我要为大家介绍几个优秀的视频素材网站,让你的抖音之路顺风顺水! …

星环科技与宁夏银行“大数据联合实验室”揭牌,持续打造金融科技新范式

5月30-31日,2024向星力未来数据技术峰会期间,在峰会现场来宾共同见证下,星环科技与宁夏银行“大数据联合实验室”正式揭牌,宁夏银行股份有限公司首席信息官崔彦刚与星环科技副总裁邱磊共同为联合实验室揭牌。 星环科技与宁夏银行借…

【每日刷题】Day92

【每日刷题】Day92 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 面试题 16.05. 阶乘尾数 - 力扣(LeetCode) 2. 取近似值_牛客题霸_牛客网 (n…

4. 最长公共前缀

4. 最长公共前缀 题目题目分析 题目 题目分析 首先要对字符串数组进行分析,字符串数组元素的最长公共前缀肯定不会超过最小元素长度,并如存在公共前缀则需遍历整个字符串元素,有点像二维数组,最后加上截取字符串加上判空操作就完…

测试——Selenium

内容大纲: 什么是自动化测试 什么是Selenium Selenium工作原理 Selenium环境搭建 Selenium API 目录 1. 什么是自动化测试 2. 什么是Selenium 3. Selenium工作原理 4. Selenium环境搭建(java) 5. Selenium API 5.1 定位元素 5.1.1 CSS选择器定位元素 5.1.2 XPath定位元…

Kubernets(k8s) 网络原理三:同主机内Pod相互访问

前两篇文章中我们介绍了pod怎么和宿主机通信以及pod怎么访问外网,这两种通信是理解pod间通信的基础。 关于pod间的相互访问,这里还需要细化一下。回想一下pod在k8s节点中的分布,两个pod可能分布在同一台宿主机上,也可能分布在不同…

ECMAScript 12 (ES12, ES2021) 新特性

还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,ech…

PXE实验

实验前准备 关闭VMware的dhcp 点击 编辑 点击 虚拟网络编辑器 选择 NAT模式 将dhcp取消勾选 准备两台虚拟机 一台试验机,(网络环境正常并且有图形化的界面的rhel7) 一台测试机 init 5 --------------> 开启图形化界面 如…

element-plus框架+vue3+echart——后台页面

一、图表样式 图表组件:echarts https://echarts.apache.org/examples/zh/index.html element-plus框架: https://www.cwgj.xyz/zh-CN/ 1、折线图 栅格 一共24。 12代表占一半50%, 当页面缩小到一定程度 占整个屏幕的100%。 id"mo…

拉刀基础知识——拉刀的种类

如前面所说:近期要围绕拉削和拉刀这个话题,分享一些相关的内容,从最基础的知识开始,为此还专门买了本旧书——《拉刀设计》入门学习。废话不多说,直接开始。 拉刀最早由冲头演变而来,用于加工方孔&#xf…