【Java面试八股文宝典之RabbitMQ篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day17

大家好,我是陶然同学,软件工程大三即将实习。认识我的朋友们知道,我是科班出身,学的还行,但是对面试掌握不够,所以我将用这100多天更新Java面试题🙃🙃。
不敢苟同,相信大家和我一样,都有一个大厂梦,作为一名资深Java选手,深知面试重要性,接下来我准备用100天时间,基于Java岗面试中的高频面试题,以每日3题的形式,带你过一遍热门面试题及恰如其分的解答。当然,我不会太深入,因为我怕记不住!!
因此,不足的地方希望各位在评论区补充疑惑、见解以及面试中遇到的奇葩问法,希望这100天能够让我们有质的飞越,一起冲进大厂!!,让我们一起学(juan)起来!!!
RabbitMQ工作原理

Broker:接收和分发消息的应用,RabbitMQ Server 就是 Message Broker
Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类
似于网络中的 namespace 概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,
可以划分出多个 vhost,每个用户在自己的 vhost 创建 exchange/queue 等
Connection:publisher/consumer 和 broker 之间的 TCP 连接
Channel:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP
Connection 的开销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如
果应用程序支持多线程,通常每个 thread 创建单独的 channel 进行通讯,AMQP method 包含了
channel id 帮助客户端和 message broker 识别 channel,所以 channel 之间是完全隔离的。
Channel 作为轻量级的Connection 极大减少了操作系统建立 TCP connection 的开销
面试题:rabbitmq为什么是基于channel(通道)去处理而不是连接?
一个应用有多个线程需要从rabbitmq中消费,或是生产消息,如果建立很多个Connection连接,对
操作系 统而言,建立和销毁tcp连接是很昂贵的开销,如果遇到使用高峰,性能瓶颈也随之显现。
rabbitmq采用类似nio的做法,连接tcp连接复用,不仅可以减少性能开销,同时也便于管理。
Queue:消息最终被送到这里等待 consumer 取走
Binding:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key,Binding
信息被保存到 exchange 中的查询表中,用于 message 的分发依据
RabbitMQ消息丢了怎么办

其中的每一步都可能导致消息丢失,常见的丢失原因包括:
- 发送时丢失:
- 生产者发送的消息未送达exchange
- 消息到达exchange后未到达queue
- MQ宕机,queue将消息丢失
- consumer接收到消息后未消费就宕机
针对这些问题,RabbitMQ分别给出了解决方案:
- 生产者确认机制
- mq持久化
- 消费者确认机制
- 失败重试机制
生产者确认机制
RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。这种机制必须给每个消
息指定一个唯一ID。消息发送到MQ以后,会返回一个结果给发送者,表示消息是否处理成功。
返回结果有两种方式:
- publisher-confirm,发送者确认
- 消息成功投递到交换机,返回ack消息未投递到交换机,返回nack
- publisher-return,发送者回执
- 消息投递到交换机了,但是没有路由到队列。返回ACK,及路由失败原因。

消息持久化
生产者确认可以确保消息投递到RabbitMQ的队列中,但是消息发送到RabbitMQ以后,如果突然宕
机,也可能导致消息丢失。
要想确保消息在RabbitMQ中安全保存,必须开启消息持久化机制。
- 交换机持久化
- 队列持久化
- 消息持久化
消费者消息确认
RabbitMQ是阅后即焚机制,RabbitMQ确认消息被消费者消费后会立刻删除。
而RabbitMQ是通过消费者回执来确认消费者是否成功处理消息的:消费者获取消息后,应该向
RabbitMQ发送ACK回执,表明自己已经处理消息。
消费失败重试机制
当消费者出现异常后,消息会不断requeue(重入队)到队列,再重新发送给消费者,然后再次异常,再次requeue,无限循环,导致mq的消息处理飙升,带来不必要的压力。
本地重试
- 开启本地重试时,消息处理过程中抛出异常,不会requeue到队列,而是在消费者本地重试
- 重试达到最大次数后,Spring会返回ack,消息会被丢弃
失败策略
在之前的测试中,达到最大重试次数后,消息会被丢弃,这是由Spring内部机制决定的。
在开启重试模式后,重试次数耗尽,如果消息依然失败,则需要有MessageRecovery接口来处
理,它包含三种不同的实现:
- RejectAndDontRequeueRecoverer:重试耗尽后,直接reject,丢弃消息。默认就是这种方式
- ImmediateRequeueMessageRecoverer:重试耗尽后,返回nack,消息重新入队
- RepublishMessageRecoverer:重试耗尽后,将失败消息投递到指定的交换机
比较优雅的一种处理方案是RepublishMessageRecoverer,失败后将消息投递到一个指定的,专门
存放异常消息的队列,后续由人工集中处理。
RabbitMQ消息重复消费
造成重复消费的原因:
MQ向消费者推送message,消费者向MQ返回ack,告知所推送的消息消费成功。但是由于网络波
动等原因,可能造成消费者向MQ返回的ack丢失。MQ长时间(一分钟)收不到ack,于是会向消
费者再次推送该条message,这样就造成了重复消费。
解决重复消费的办法:
用从存储(redis或者mysql)记录一下已经消费的message的id,当message被消费前先去存储中
查一下消费记录,没有该条message的id则正常消费返回ack,有该条message的id的话不用消费
直接返回ack给MQ。
当然实际生产中的话选用redis是比较好的选择,毕竟查mysql要进行磁盘IO,效率要低得多,而且
绝大多数重复消费都是由于MQ没有收到消费者的ack于是造成MQ再次向消费者进行同一条
message的投递。所以message的消费记录其实我们并不需要一直记录,只需要保存一段时间,当
下次投递过来的时候消费者能查到消费记录然后准确返回ack给MQ就行。
以下是一个使用redis解决重复消费的示例步骤:
监听器接收MQ队列中的数据。
利用redis的setnx命令,以消息唯一id为key,以消息内容为value,超时时间设置为10分钟,存入
redis中。
如果能够成功存入,说明没有重复消费,则处理业务,处理完业务后返回ack或者nack确认。
如果存不进去,则说明重复消费,直接返回ack确认的回调信息就可以了。
相关文章:
【Java面试八股文宝典之RabbitMQ篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day17
大家好,我是陶然同学,软件工程大三即将实习。认识我的朋友们知道,我是科班出身,学的还行,但是对面试掌握不够,所以我将用这100多天更新Java面试题🙃🙃。 不敢苟同,相信大…...
ESP32开发(1)----Espressif-IDE开发环境配置
Espressif-IDE开发环境配置前言一、ESP32-WROOM-32介绍二、IDE环境搭建三、建立第一个项目总结前言 最近得到一块ESP32-WROOM-32的开发板,没有原理图,但板子走线比较简单,看着板子上的布线大致猜一猜连接,然后试玩了一下…...
MyBatisPlus标准数据层开发
MyBatisPlus标准数据层开发2,标准数据层开发2.1 标准CRUD使用2.2 新增2.3 删除2.4 修改2.5 根据ID查询2.6 查询所有2.7 Lombok概念使用步骤步骤1:添加lombok依赖步骤2:安装Lombok的插件步骤3:模型类上添加注解2.8 分页功能步骤1:调用方法传入参数获取返回值步骤2:设…...
C/C++每日一练(20230412)
目录 1. 二维数组找最值 🌟🌟 2. 排序 🌟 3. 二叉树展开为链表 🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏 1. 二维…...
Leetcode.1379 找出克隆二叉树中的相同节点
题目链接 Leetcode.1379 找出克隆二叉树中的相同节点 easy 题目描述 给你两棵二叉树,原始树 original和克隆树 cloned,以及一个位于原始树 original中的目标节点 target。 其中,克隆树 cloned是原始树 original的一个 副本 。 请找出在树 …...
2022年团体程序设计天梯赛-总决赛
目录 一、L1-1 今天我要赢 二、L1-2 种钻石 三、L1-3 谁能进图书馆 四、L1-4 拯救外星人 五、L1-5 试试手气 六、L1-6 斯德哥尔摩火车上的题 七、L1-7 机工士姆斯塔迪奥 八、L1-8 静静的推荐 九、L2-1 插松枝 十、L2-2 老板的作息表 十一、L2-3 龙龙送外卖 十二、L…...
大数据技术之Sqoop——SQL to Hadoop
一、简介sqoop (sql to hadoop)是一款开源的工具,主要用于在 Hadoop(Hive)与传统的数据库(mysql、postgresql...)间进行数据的传递,可以将一个关系型数据库(例如 : MSQL,Oracle,Post…...
Java议题
序号议题 解释MyBatis官网1mapper文件中什么时候使用 # 什么时候必须用 $ 1、关键字作为参数,使用"$",两边不加""。 2、非关键字作为参数,使用"#"防注入。 其他情况优先使用"#" 2主键回填࿰…...
【阅读论文】USAD:多变量时间序列上的无监督异常检测
USAD : UnSupervised Anomaly Detection on Multivariate Time Series 摘要 IT系统的自动监控是Orange目前面临的挑战。考虑到其IT运营所达到的规模和复杂性,随着时间的推移,用于推断正常和异常行为的测量所需的传感器数量急剧增加,使得传统…...
Java多线程:ReentrantLock中的方法
公平锁与非公平锁 ReentrantLock有一个很大的特点,就是可以指定锁是公平锁还是非公平锁,公平锁表示线程获取锁的顺序是按照线程排队的顺序来分配的,而非公平锁就是一种获取锁的抢占机制,是随机获得锁的,先来的未必就一…...
RabbitMQ初识快速入门
RabbitMQ初识&快速入门1.初识MQ1.1.同步和异步通讯1.1.1.同步通讯1.1.2.异步通讯1.2.技术对比:2.快速入门2.1.安装RabbitMQ2.1.1 下载镜像2.1.2 安装MQ2.2.RabbitMQ消息模型2.3.导入Demo工程2.4.入门案例2.4.1.publisher实现2.4.2.consumer实现2.5.总结1.初识MQ…...
由浅入深了解HashMap源码
由经典面试题引入,讲解一下HashMap的底层数据结构?这个面试题你当然可以只答,HashMap底层的数据结构是由(数组链表红黑树)实现的,但是显然面试官不太满意这个答案,毕竟这里有一个坑需要你去填&a…...
P5318 【深基18.例3】查找文献
题目描述 小K 喜欢翻看洛谷博客获取知识。每篇文章可能会有若干个(也有可能没有)参考文献的链接指向别的博客文章。小K 求知欲旺盛,如果他看了某篇文章,那么他一定会去看这篇文章的参考文献(如果他之前已经看过这篇参考…...
Error caught was: No module named ‘triton‘
虽然报错但是不影响程序运行: A matching Triton is not available, some optimizations will not be enabled. Error caught was: No module named triton解决: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple triton2.0.0.dev20221120...
Ruby设计-开发日志
Log 1 产品 Product 1.1 创建 Product 创建名为 project 的 rails 应用 rails new project创建 Product 模型 rails generate scaffold Product title:string description:text image_url:string price:decimal这会生成一个 migration ,我们需要进一步修改这个…...
SpringBoot 调用外部接口的三种方式
方式一:使用原始httpClient请求 /** description get方式获取入参,插入数据并发起流程* params documentId* return String*/ RequestMapping("/submit/{documentId}") public String submit1(PathVariable String documentId) throws ParseE…...
C 中的结构体
C 中的结构体 C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。 结构体中的数据成员可以是基本数据类型(如 int、float、char 等),也可以…...
nodejs安装教程
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,可以用于在服务器端运行 JavaScript 代码。以下是 Node.js 的安装教程: 步骤 1:下载 Node.js 访问 Node.js 的官方网站 https://nodejs.org/,进入官方下载页面。 在下载页…...
【华为OD机试】1029 - 整数与IP地址间的转换
文章目录一、题目🔸题目描述🔸输入输出🔸样例1二、代码参考作者:KJ.JK🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 &#x…...
【FPGA实验1】FPGA点灯工程师养成记
对于FPGA几个与LED相关的实验(包括按键点灯、流水灯、呼吸灯等)的记录,方便日后查看。这世界上就又多了一个FPGA点灯工程师了😏 成为一个FPGA点灯工程师分三步:一、按键点灯1、按键点灯程序2、硬件实现二、流水灯1、流…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
