面试之消息队列

消息队列场景

什么是消息队列?

  消息队列是一个使用队列来通信的组件,它的本质就是个转发器,包含发消息、存消息、消费消息。
在这里插入图片描述

消息队列怎么选型?

特性ActiveMQRabbitMQRocketMQKafka
单机吞吐量万级万级10万级10万级
时效性毫秒级微秒级毫秒级毫秒级
可用性高(主从)高(主从)非常高(分布式)非常高(分布式)
消息重复至少一次至少一次至少一次 最多一次至少一次最多一次
消息顺序性有序有序有序分区有序
支持主题数千级百万级千级百级,多了性能严重下滑
消息回溯不支持不支持支持(按时间回溯)支持(按offset回溯)
管理界面普通普通完善普通

消息队列使用场景有哪些?

  • 异步处理:缩短用户响应时间,提高系统吞吐量,各服务可独立运行,互不干扰。
  • 应用解耦:降低系统间耦合度,一个系统的变更或故障不易影响其他系统,提升系统可维护性与扩展性。
  • 流量削峰:保护后端服务不被高流量冲垮,可按下游处理能力调节流量,避免系统崩溃 。

消息重复消费怎么解决?

  业务端对于已经消费成功的消息,保存在本地数据库或Redis缓存业务中,进行业务表示,每次处理前先进行校验,保证幂等性。

消息丢失怎么解决的?

在这里插入图片描述
  消息生产阶段:只要能正常接收到MQ中间件的ack确认响应,就表示发送成功,所以只要处理号消息的返回值和异常,如果返回异常则进行消息重发,那么这个阶段是不会出现消息丢失的。
  消息存储阶段:生产者在发布消息是,MQ中间件通常会写入多个节点,也就是创建多个副本,即便其中一个节点挂掉,也能保证集群的数据不丢失。
  消息消费阶段:消费者接收消息并处理消息之后,才回复ack的话,那么消息是不会丢失的。不能收到消息就会回ack,否则可能消息处理中途就挂掉了,消息便丢失了。

消息队列的可靠性怎么保证?

  消息持久化:在系统崩溃、重启或者网络故障等情况下,未处理的消息不会丢失。
  消息确认机制:消费者在成功处理消息后,应该向消息队列发送确认(ack)。消息队列只有收到确认后,才会将消息从队列中移除。如果没有收到确认,消息队列会在一定时间内重发消息给消费者。
  消息重试策略:当消费者处理消息失败后,需要选择合适的重试策略。可以是设置重试次数和重试间隔时间;也可以是发送消息到死信队列中,以便后续的排查和处理。

消息队列的顺序性怎么保证?

  有序消息处理场景的识别:明确业务场景中哪些消息是需要保证顺序的,对于需要顺序处理的消息,要确保消息队列和消费者能够按照特定的顺序进行处理。
  消息队列对顺序性的支持:Kafka可以通过将消息划分到同一个分区(Partition)来保证消息在分区内是有序的,消费者按照分区顺序读取消息就可以保证消息顺序。但这也可能会限制消息的并行处理程度,需要在顺序性和吞吐量之间进行权衡。
  消费者顺序处理消息:消费者在处理消息时,应该避免并发处理可能导致的打乱情况。可以使用单线程或者使用对顺序消息进行串行化处理后的线程池等方法,确保消息按照正确的顺序被消费。

如何保证幂等性?

幂等性:同一操作的多次执行对系统状态的影响与一次执行结果一致。

实现幂等性的核心方案:

  • 唯一标识(幂等键):客户端为每一个请求生成全局唯一ID,服务端校验该ID是否已处理,适用于场景:接口调用、消息消费等。
  • 数据库事务+乐观锁:通过版本号或状态字段控制并发更新,确保多次更新等同于单次操作,适用场景:数据库记录更新(如余额扣减、订单状态变更)。
  • 数据库唯一约束:利用数据库唯一索引防止重复数据写入,适用场景:数据插入(如订单创建)。
  • 分布式锁:通过锁机制保证同一时刻仅有一个请求执行关键操作,适用场景:高并发下的资源抢夺(如秒杀)。
  • 消息去重:消息队列生产者为每一条消息生成唯一的消息ID,消费者在处理消息前,先检查该消息ID是否已经处理过,如果已经处理过则丢弃该消息。

如何处理消息队列的消息积压问题?

原因:生产者的生产速度大于消费者的消费速度。

解决方案

  • 批量处理消息
  • 增加Topic的队列数和消费组机器的数量
  • 临时紧急扩容

临时紧急扩容的大概思路:
1.先修复consumer消费者的问题,以确保其恢复消费速度,然后将现有consumer都停掉。
2.新建一个topic,partition是原来的10倍。临时建立好原先10倍数量的queue。
3.写一个临时的分发数据的cunsumer程序,这个程序部署上去,消费积压的数据,消费之后不做耗时的处理,直接轮询写入临时建立好的10倍数量的queue。
4.接着临时征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的数据。这个做法相当于是临时将queue资源和consumer资源扩大10倍,以正常的10倍速度来消费数据。
5.等消息消费完积压的数据后,恢复原先的部署架构,重新用原先的consumer机器来消费消息。

如何保证数据一致性,事务消息如何实现?

在这里插入图片描述

  1. 生产者产生消息,发送带MQ服务器
  2. MQ收到消息后,将消息持久化到存储系统。
  3. MQ服务器返回Ack到生产者。
  4. MQ服务器把消息push给消费者
  5. 消费者消费完消息,响应ACK
  6. MQ服务器收到ACK,认为消息消费成功,即在存储中删除消息。
    在这里插入图片描述
  7. 生产者产生消息,发送一条半事务消息到MQ服务器
  8. MQ收到消息后,将消息持久化到存储系统,这条消息的状态是待发送状态。
  9. MQ服务器返回ACK确认到生产者,此时MQ不会触发消息推送事件
  10. 生产者执行本地事务
  11. 如果本地事务执行成功,即commit执行结果到MQ服务器;如果执行失败,发送rollback。
  12. 如果是正常的commit,MQ服务器更新消息状态为可发送;如果是rollback,即删除消息。
  13. 如果消息状态更新为可发送,则MQ服务器会push消息给消费者。消费者消费完就回ACK。
  14. 如果MQ服务器长时间没有收到生产者的commit或者rollback,它会反查生产者,然后根据查询到的结果执行最终状态。

消息队列是参考哪种设计模式?

观察者模式
观察者模式实际上就是一对多的关系,即存在一个主题和多个观察者,主题也是被观察者,当主题发布消息时,会通知各个观察者,观察者将会收到最新消息。
在这里插入图片描述
发布订阅模式
发布订阅模式和观察者模式的区别就是发布者和订阅者完全解耦,通过中间的发布订阅中心进行消息通知,发布者并不知道自己发布的消息会通知给谁。
在这里插入图片描述

让你写一个消息队列,该如何进行架构设计?

在这里插入图片描述

  1. 首先是消息队列的整体流程,producer发送消息给broker,broker存储好,broker再发送给consumer消费,consumer回复消费确认等。
  2. producer发送消息给broker,broker发消息给consumer消费,那就需要两次RPC了,RPC如何设计呢?可以参考开源框架Dubbo,你可以说说服务发现、序列化协议等等
  3. broker考虑如何持久化呢,是放文件系统还是数据库呢,会不会消息堆积呢,消息堆积如何处理呢。
  4. 消费关系如何保存呢?点对点还是广播方式呢?广播关系又是如何维护呢?zk还是config server
  5. 消息可靠性如何保证呢?如果消息重复了,如何幂等处理呢?
  6. 消息队列的高可用如何设计呢?可以参考Kafka的高可用保障机制。多副本 -> leader & follower -> broker挂了重新选举leader即可对外服务。
  7. 消息事务特性,与本地业务同个事务,本地消息落库;消息投递到服务端,本地才删除;定时任务扫描本地消息库,补偿发送。
  8. MQ得伸缩性和可扩展性,如果消息积压或者资源不够时,如何支持快速扩容,提高吞吐?可以参照一下Kafka的设计理念,broker -> topic -> partition,每个partition放一个机器,就存一部分数据。如果现在资源不够了,简单啊,给topic增加partition,然后做数据迁移,增加机器,不就可以存放更多数据,提供更高的吞吐量了。

RocketMQ

消息队列为什么选择RocketMQ的?

  • 开发语言优势:RocketMQ使用Java语言开发,更容易上手和阅读源码。
  • 社区氛围活跃:RocketMQ是阿里巴巴开源且内部在大量使用的消息队列,是经得起考验的,并且能够针对线上的复杂环境提供相应的解决方案。
  • 特性丰富:RocketMQ的高级特性达到了12种,例如顺序消息、事务消息、消息过滤、定时消息等。丰富的特性,能够为我们复杂的业务场景尽可能多地提供思路和解决方案。

RocketMQ和Kafka的区别是什么?如何做技术选型?

Kafka的优缺点

  • 优点:Kafka的最大优势在于它的高吞吐量。Kafka支持集群部署,如果部分机器宕机不可用,则不影响Kafka的正常使用。
  • 缺点:Kafka有可能造成数据丢失,因为它在收发消息的时候,并不是直接写入物理磁盘中,而是写入到磁盘缓冲区里面的。Kafka功能比较单一,主要就是支持收发消息,造成使用场景受限。

RocketMQ的优缺点

  • 优点:支持功能多,比如延迟队列、消息事务等等,吞吐量也高,支持大规模集群部署,线性扩展方便,Java语言开发,满足了国内绝大多数公司的技术栈。
  • 缺点:性能相比Kafka弱一些,因为kafka用到了sendfile的零拷贝技术,而RockMQ主要是用mmap+write来实现零拷贝。

怎么选择呢?

  • 如果业务只是收发消息,而且允许小部分的数据丢失,但要求极高的吞吐量和高性能的话,选择kafka。
  • 如果公司需要通过mq实现一些业务需求,比如延迟队列、消息事务等,且公司技术栈主要是Java的话,选RocketMQ

RocketMQ延时消息的底层原理

在这里插入图片描述  broker在接受到消息的时候,会将延时消息存入到延时的Topic的队列中,然后ScheduleMessageService对每个queue对应的定时任务不停的执行,检查queue中哪些消息已到设定时间,然后转发到消息的原始Topic,这些消息就会被各自的producer消费了。

RocektMQ怎么处理分布式事务?

  RocketMQ是一种最终一致性的分布式事务。
在这里插入图片描述分布式事务的流程如上图:

  1. A服务先发送个Half Message (是指暂不能被Consumer消费的消息。Producer已经把消息成功发送到了Broker端,但此消息被标记为暂不能投递状态,处于该种状态下的消息称为半消息。需要Producer对消息的二次确认后,Consumer才能去消费它) 给Brock端。
  2. 当A服务知道Half Message发送成功后,那么开始第3步执行本地事务。
  3. 执行本地事务(会有三种情况1、执行成功。2、执行失败。3、网络等原因导致没有响应)
    1. 如果本地事务成功,那么Product像Brock服务器发送Commit,这样B服务就可以消费该message。
    2. 如果本地事务失败,那么Product像Brock服务器发送Rollback,那么就会直接删除上面这条半消息。
    3. 如果因为网络等原因迟迟没有返回失败还是成功,那么会执行RocketMQ的回调接口,来进行事务的回查。

从上面流程可以得知 只有A服务本地事务执行成功 ,B服务才能消费该message。

如果B最终执行失败,几乎可以断定就是代码有问题导致的异常,因为消费端RocketMQ有重试机制,如果不是代码问题一般重试击此就可以成功。
如果是代码的原因引起多次重试失败后,也没有关系,将异常记录下来,由人工处理。

RocketMQ消息顺序怎么保证?

  • RocketMQ采用了局部顺序一致性的机制,实现了单个队列中的消息严格有序。
  • 在Producer(生产者)把一批需要保证顺序的消息发送给同一个MessageQueue。
  • Consumer(消费者)则通过加锁的机制来保证消息消费的顺序性,Broker端通过对MessageQueue进行加锁,保证同一个MessageQueue只能被同一个Consumer进行消费。

RocketMQ怎么保证消息不被重复消费

  在业务逻辑中实现幂等性,确保即使消息被重复消费,也不会影响业务状态。

RocketMQ消息积压了,怎么办?

  • 扩展消费端的实例数来提升总体的消费能力。
  • 如果短时间内没有足够的服务器资源进行扩容,可进行系统降级,通过关闭一些不重要的业务,减少发送方的数据量,最低限度地让系统还能正常运转,服务一些重要业务。

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

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

相关文章

GStreamer 简明教程(十一):插件开发,以一个音频生成(Audio Source)插件为例

系列文章目录 GStreamer 简明教程(一):环境搭建,运行 Basic Tutorial 1 Hello world! GStreamer 简明教程(二):基本概念介绍,Element 和 Pipeline GStreamer 简明教程(三…

Linux kernel signal原理(下)- aarch64架构sigreturn流程

一、前言 在上篇中写到了linux中signal的处理流程,在do_signal信号处理的流程最后,会通过sigreturn再次回到线程现场,上篇文章中介绍了在X86_64架构下的实现,本篇中介绍下在aarch64架构下的实现原理。 二、sigaction系统调用 #i…

华为OD机试真题——简易内存池(2025A卷:200分)Java/python/JavaScript/C++/C/GO最佳实现

2025 A卷 200分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式! 本文收录于专栏:《2025华为OD真题目录全流程解析/备考攻略/经验…

腾讯一面面经:总结一下

1. Java 中的 和 equals 有什么区别?比较对象时使用哪一个 1. 操作符: 用于比较对象的内存地址(引用是否相同)。 对于基本数据类型、 比较的是值。(8种基本数据类型)对于引用数据类型、 比较的是两个引…

计算机网络中的DHCP是什么呀? 详情解答

目录 DHCP 是什么? DHCP 的工作原理 主要功能 DHCP 与网络安全的关系 1. 正面作用 2. 潜在安全风险 DHCP 的已知漏洞 1. 协议设计缺陷 2. 软件实现漏洞 3. 配置错误导致的漏洞 4. 已知漏洞总结 举例说明 DHCP 与网络安全 如何提升 DHCP 安全性 总结 D…

2025 年导游证报考条件新政策解读与应对策略

2025 年导游证报考政策有了不少新变化,这些变化会对报考者产生哪些影响?我们又该如何应对?下面就为大家详细解读新政策,并提供实用的应对策略。 最引人注目的变化当属中职旅游类专业学生的报考政策。以往,中专学历报考…

【物联网】基于LORA组网的远程环境监测系统设计(ThingsCloud云平台版)

演示视频: 基于LORA组网的远程环境监测系统设计(ThingsCloud云平台版) 前言:本设计是基于ThingsCloud云平台版,还有另外一个版本是基于机智云平台版本,两个设计只是云平台和手机APP的区别,其他功能都一样。如下链接: 【物联网】基于LORA组网的远程环境监测系统设计(机…

SQL 函数进行左边自动补位fnPadLeft和FORMAT

目录 1.问题 2.解决 方式1 方式2 3.结果 1.问题 例如在SQL存储过程中,将1 或10 或 100 长度不足的时候,自动补足长度。 例如 1 → 001 10→ 010 100→100 2.解决 方式1 SELECT FORMAT (1, 000) AS FormattedNum; SELECT FORMAT(12, 000) AS Form…

Nacos简介—2.Nacos的原理简介

大纲 1.Nacos集群模式的数据写入存储与读取问题 2.基于Distro协议在启动后的运行规则 3.基于Distro协议在处理服务实例注册时的写路由 4.由于写路由造成的数据分片以及随机读问题 5.写路由 数据分区 读路由的CP方案分析 6.基于Distro协议的定时同步机制 7.基于Distro协…

中电金信联合阿里云推出智能陪练Agent

在金融业加速数智化转型的今天,提升服务效率与改善用户体验已成为行业升级的核心方向。面对这一趋势,智能体与智能陪练的结合应用,正帮助金融机构突破传统业务模式,开拓更具竞争力的创新机遇。 在近日召开的阿里云AI势能大会期间&…

十分钟恢复服务器攻击——群联AI云防护系统实战

场景描述 服务器遭遇大规模DDoS攻击,导致服务不可用。通过群联AI云防护系统的分布式节点和智能调度功能,快速切换流量至安全节点,清洗恶意流量,10分钟内恢复业务。 技术实现步骤 1. 启用智能调度API触发节点切换 群联系统提供RE…

LLM量化技术全景:GPTQ、QAT、AWQ、GGUF与GGML

01 引言 本文介绍的是在 LLM 讨论中经常听到的各种量化技术。本文的目的是提供一步一步的解释和代码,让大家可以自己使用这些技术来压缩模型。 闲话少说,我们来研究一下吧! 02 Quantization 量化是指将高精度数字转换为低精度数字。低精…

IP的基础知识以及相关机制

IP地址 1.IP地址的概念 IP地址是分配给连接到互联网或局域网中的每一个设备的唯一标识符 也就是说IP地址是你设备在网络中的定位~ 2.IP版本~ IP版本分为IPv4和IPv6,目前我们最常用的还是IPv4~~但是IPv4有个缺点就是地址到现在为止,已经接近枯竭~~&…

本地使用Ollama部署DeepSeek

以下是在本地使用Ollama部署DeepSeek的详细教程,涵盖安装、修改安装目录、安装大模型以及删除大模型的操作步骤。 安装Ollama 1. 系统要求 确保你的系统满足以下条件: 操作系统:macOS、Linux或者Windows。足够的磁盘空间和内存。 2. 安装…

开源项目实战学习之YOLO11:ultralytics-cfg-datasets-Objects365、open-images-v7.yaml文件(六)

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 medical - pills.yaml 通常用于配置与医学药丸检测任务相关的参数和信息 Objects365.yaml 用于配置与 Objects365 数据集相关信息的文件。Objects365 数据集包含 365 个不同的物体类别…

23种设计模式-行为型模式之策略模式(Java版本)

Java 策略模式(Strategy Pattern)详解 🧠 什么是策略模式? 策略模式是一种行为型设计模式,它定义了一系列算法,把它们一个个封装起来,并且使它们可以互相替换。策略模式让算法独立于使用它的客…

使用 AI Agent 改善师生互动的设计文档

使用 AI Agent 改善师生互动的设计文档 一、引言 1.1 研究背景 当前教育领域的师生互动存在诸多挑战,如教师负担过重、学生个体差异大导致难以满足所有人的需求,以及信息传递延迟等问题。引入AI-Agent能够有效缓解这些问题,通过自动化手段协…

2、Ubuntu 环境下安装RabbitMQ

⼀. 安装Erlang RabbitMqRabbitMq需要Erlang语⾔的⽀持,在安装rabbitMq之前需要安装erlang需要Erlang语⾔的⽀持,在安装rabitMq之前需要安装erlang。 安装erlang # 更新软件包 sudo apt-get update # 安装 erlang sudo apt-get install erlang 查看er…

Node.js 操作 ElasticSearch 完整指南:从安装到实战

本文将手把手教你如何搭建 ElasticSearch 环境,并通过 Node.js 实现高效数据检索。包含 10 个可直接复用的代码片段,助你快速掌握搜索、聚合等核心功能! 环境搭建篇 1. ElasticSearch 安装要点 下载 es下载连接 下载下来后,进…

硬核科普丨2025年安全、高效网络准入控制系统深度解析

阳途网络准入控制系统(Network Access Control,简称NAC)是当代网络安全领域的重要工具,有效防止未经授权的访问和数据泄露,保障网络资源的安全性和完整性。本文将深入探讨阳途网络准入控制系统的的重要性和作用。 一、…