面试之消息队列

news2025/4/25 15:19:41

消息队列场景

什么是消息队列?

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

消息队列怎么选型?

特性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种,例如顺序消息、事务消息、消息过滤、定时消息等。丰富的特性,能够为我们复杂的业务场景尽可能多地提供思路和解决方案。

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

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

相关文章

通过阿里云Milvus与通义千问VL大模型,快速实现多模态搜索

本文主要演示了如何使用阿里云向量检索服务Milvus版与通义千问VL大模型,提取图片特征,并使用多模态Embedding模型,快速实现多模态搜索。 基于灵积(Dashscope)模型服务上的通义千问 API以及Embedding API来接入图片、文…

使用 Spring Boot Admin 通过图形界面查看应用配置信息的完整配置详解,包含代码示例和注释,最后以表格总结关键配置

以下是使用 Spring Boot Admin 通过图形界面查看应用配置信息的完整配置详解,包含代码示例和注释,最后以表格总结关键配置: 1. 环境准备 Spring Boot 版本:2.7.x(兼容 Spring Boot Admin 2.x)Spring Boot…

【计算机视觉】CV实战项目 - 基于YOLOv5与DeepSORT的智能交通监控系统:原理、实战与优化

基于YOLOv5与DeepSORT的智能交通监控系统:原理、实战与优化 一、项目架构与技术解析1.1 核心算法架构1.2 学术基础 二、实战环境配置2.1 硬件要求与系统配置2.2 分步安装指南 三、核心功能实战3.1 基础车辆计数3.2 自定义检测类别3.3 多区域计数配置 四、性能优化技…

17.磁珠在EMC设计中的运用

磁珠在EMC设计中的运用 1. 磁珠的高频等效特性2. 磁珠的参数分析与选型3. 磁珠应用中的隐患问题 1. 磁珠的高频等效特性 和磁环类似,低频段感性jwL为主,高频段阻性R为主。 2. 磁珠的参数分析与选型 不需要太在意磁珠在100MHz时的电阻值,选型…

Mediamtx与FFmpeg远程与本地推拉流使用

1.本地推拉流 启服 推流 ffmpeg -re -stream_loop -1 -i ./DJI_0463.MP4 -s 1280x720 -an -c:v h264 -b:v 2000k -maxrate 2500k -minrate 1500k -bufsize 3000k -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/stream 拉流 ffplay -rtsp_transport tcp rtsp://43.136.…

DPIN在AI+DePIN孟买峰会阐述全球GPU生态系统的战略愿景

DPIN基金会在3月29日于印度孟买举行的AIDePIN峰会上展示了其愿景和未来5年的具体发展计划,旨在塑造去中心化算力的未来。本次活动汇集了DPIN、QPIN、社区成员和Web3行业资深顾问,深入探讨DPIN构建全球领先的去中心化GPU算力网络的战略,该网络…

Visual Studio Code 使用tab键往左和往右缩进内容

使用VSCode写东西,经常遇到多行内容同时缩进的情况,今天写文档的时候就碰到,记录下来: 往右缩进 选中多行内容,点tab键,会整体往右缩进: 往左缩进 选中多行内容,按shifttab&am…

HTML、XHTML 和 XML区别

HTML、XHTML 和 XML 这三兄弟的区别 HTML: 老大哥,负责网页长啥样,性格比较随和,有点小错误也能容忍。XHTML: 二哥,看着像 HTML,但规矩严,是按 XML 的规矩来的 HTML,更规范。XML: 小弟,负责存储和传输数据,非常灵活,标签可以自己随便定,但规矩最严。它们仨长啥样?(…

FPGA上实现YOLOv5的一般过程

在FPGA上实现YOLOv5 YOLO算法现在被工业界广泛的应用,虽说现在有很多的NPU供我们使用,但是我们为了自己去实现一个NPU所以在本文中去实现了一个可以在FPGA上运行的YOLOv5。 YOLOv5的开源代码链接为 https://github.com/ultralytics/yolov5 为了在FPGA中…

4U带屏基于DSP/ARM+FPGA+AI的电力故障录波装置设计方案,支持全国产化

4U带屏DSP/ARMFPGAAI电力故障录波分析仪,支持国产化,含有CPU主控模块,96路模拟量采集,256路开关量,通讯扩展卡等#电力故障录波#4U带屏#新能源#电力监测 主要特点 1)是采用嵌入式图形系统,以及…

数据库数据删除与修改实验

数据库数据删除与修改实验 在数据库原理的学习中,数据的删除与修改是核心操作技能。通过“删除修改数据”实验,我系统实践了 SQL 中 UPDATE 和 DELETE 语句的多种应用场景,从基础语法到复杂业务逻辑处理,积累了丰富的实战经验。本…

【含文档+PPT+源码】基于SpringBoot+vue的疫苗接种系统的设计与实现

项目介绍 本课程演示的是一款 基于SpringBootvue的疫苗接种系统的设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系…

项目自动化测试

一.设计测试用例(细致全面) 二.先引入所需要的pom.xml依赖 1.selenium依赖 2.webdrivermanager依赖 3.commons-io依赖 编写测试用例–按照页面对用例进行划分,每个页面是Java文件,页面下的所有用例统一管理 三.common包(放入公用包) 类1utils 可以调用driver对象,访问url …

Python爬虫爬取图片并存储到MongoDB(注意:仅尝试存储一条空的示例数据到MongoDB,验证MongoDB的联通性)

以下是一个使用Python爬取图片并存储到MongoDB的示例实现,包含详细步骤说明: import requests from bs4 import BeautifulSoup from pymongo import MongoClient from datetime import datetime import os import re# 配置信息 mongoIP mongodb://root…

L1-1、Prompt 是什么?为什么它能“控制 AI”?

*Prompt 入门 L1-1 想象一下,你只需输入一句话,AI 就能自动为你写一篇文案、生成一份报告、甚至规划你的创业计划。这种“对话即编程”的背后魔法,就是 Prompt 的力量。 🔍 一、Prompt 的定义与由来 Prompt(提示词&am…

TIM输入捕获知识部分

越往左,频率越高;越往右,频率越低。【越紧凑,相同时间,次数越多】 计算频率的方法:测评法、测周法、中界频率。 频率的定义:1s内出现了多少个重复的周期 测评法就是从频率的定义出发的&#…

PCB常见封装类型

1. 电阻、电容、电感封装 2. 二极管、三极管封 3. 排阻类器件(8脚、16脚)封装 4. SO类器件(间距有1.27、2.54mm等)封装 5. QFP类器件封装(四方扁平封装) 结构:引脚分布在封装的四个侧面&#…

【Linux】调试工具gdb的认识和使用指令介绍(图文详解)

目录 1、debug和release的知识 2、gdb的使用和常用指令介绍: (1)、windows下调试的功能: (2)、进入和退出: (3)、调试过程中的相关指令: 3、调试究竟是在…

UML设计系列(9):开发过程中如何应用UML

传送门 UML设计系列(1):状态机图 UML设计系列(2):类图 UML设计系列(3):时序图 UML设计系列(4):用例图 UML设计系列(5):系统依赖图 UML设计系列(6):活动图 UML设计系列(7):UML设计阶段性总…

模板方法模式:定义算法骨架的设计模式

模板方法模式:定义算法骨架的设计模式 一、模式核心:模板方法定义算法骨架,具体步骤延迟到子类实现 在软件开发中,经常会遇到这样的情况:某个算法的步骤是固定的,但具体步骤的实现可能因不同情况而有所不…