Java后端面试题(mq相关)(day9)
目录
- 为什么用MQ? 异步 、削峰、解耦
- 1. 异步处理
- 2. 解耦
- 3. 削峰填谷
- Exchange类型
- 什么是死信队列?
- 如何保证消息的可靠性?
- RabbitMQ中如何解决消息堆积问题?
- RabbitMQ中如何保证消息有序性?
- 如何防止消息重复消费?(如何保证消息幂等性)
为什么用MQ? 异步 、削峰、解耦
MQ(Message Queue,消息队列)是一种在分布式系统中进行消息传递的技术,它主要用于实现服务间的 解耦、异步处理、削峰填谷等功能。下面我将分别解释这几个概念,并说明它们是如何通过MQ实现的。
1. 异步处理
异步处理是指一个操作不需要等待另一个操作完成就可以继续执行的过程。
- 在传统的同步模式下,客户端发送请求后必须等待服务器响应才能继续执行后续操作;
- 而在异步模式下,客户端发送请求后无需等待,可以立即返回并执行其他任务,服务器处理完请求后再通知客户端结果。
MQ如何实现异步处理:
- 当客户端向服务端发送请求时,该请求不是直接被服务端处理,而是先存入MQ中。
- 服务端从MQ中获取请求消息后进行处理,客户端无需等待服务端处理完成即可继续执行其他任务。
- 这种方式提高了系统的响应速度和吞吐量,使得系统能够处理更多的并发请求。
2. 解耦
解耦是指降低系统各组件之间的依赖性,使得每个组件都可以独立地开发、部署和扩展。这有助于提高系统的灵活性和可维护性。
MQ如何实现解耦:
- 发送方将消息发送到MQ中,而接收方从MQ中读取消息。这样发送方和接收方之间就不存在直接的调用关系。
- 即使接收方暂时不可用,发送方也可以继续发送消息,因为消息会被暂存在MQ中,直到接收方恢复可用。
- 发送方和接收方可以独立扩展,而不影响彼此的工作。
3. 削峰填谷
削峰填谷是指通过缓存、异步处理等手段来平衡系统的负载,避免高峰期系统过载或低谷期资源浪费的情况。
MQ如何实现削峰填谷:
- 在高流量期间,系统产生的大量消息会被存入MQ中,而不是直接由后端服务处理。这可以防止后端服务因短时间内处理大量请求而过载。
- 当流量高峰过去后,后端服务可以从MQ中慢慢消费这些消息,从而平衡处理过程,确保服务质量。
- 通过这种方式,系统能够在高峰期吸收额外的请求,在低谷期释放资源,从而达到资源的有效利用。
综上所述,MQ作为一种重要的中间件技术,对于提升系统的性能、稳定性和可扩展性具有重要作用。
Exchange类型
常用的交换机有以下三种,因为消费者是从队列获取信息的,队列是绑定交换机的,所以对应的消息推送/接收模式也会有以下几种:
- Direct Exchange
直连型交换机,根据RoutingKey(路由键)路由到不同的队列 - Fanout Exchange
扇型(广播)交换机,这个交换机没有路由键概念,就算你绑了路由键也是无视的。 这个交换机在接收到消息后,会直接转发到绑定到它上面的所有队列。 - Topic Exchange
主题交换机,这个交换机其实跟直连交换机流程差不多,但是它的特点就是在它的路由键和绑定键之间是有规则的。
简单地介绍下规则:
*(星号) 用来表示一个或多个字符#(井号) 用来表示任意数量的字符
什么是死信队列?
-
死信(Dead Letter):是指在消息队列系统中那些无法被正常消费的消息。
-
死信队列(Dead Letter Queue, DLQ):当消息无法被正常处理时,也就是死信,可以将这些死信发送到一个专门的队列中,以便于后续检查和处理
以下是一些可能导致消息成为死信的情况:
- 消息被拒绝访问:消费者显式地拒绝了消息(使用 channel.BasicNack 或 channel.BasicReject 方法),并且设置了 requeue 参数为 false,这意味着消息不应该被重新放回原队列。
- 消费者发生异常,超过重试次数 。 (其实spring框架调用的就是 basicNack)
- 消息过期:如果消息设置了生存时间(Time To Live, TTL),并且超过了这个时间限制,消息就会变为死信。
- 队列达到最大长度:如果消息队列达到了最大长度限制,新的消息将无法加入队列,这时这些新消息也会变成死信。
如何保证消息的可靠性?
消息丢失场景:
- 消息到 MQ 的过程中搞丢
- MQ 自己搞丢
- MQ 到消费过程中搞丢。
生产端消息可靠性保证:
-
消息持久化:
当生产者发布消息时,可以选择将其标记为持久化到磁盘上。 -
确认(Confirm)机制:
开启confirm回调模式后,RabbitMQ会在消息成功写入到磁盘并至少被一个交换器接受后,向生产者发送一个确认(acknowledgement)。若消息丢失或无法投递给任何队列,RabbitMQ将会发送一个否定确认(nack). 生产者可以根据这些确认信号判断消息是否成功送达并采取相应的重试策略。
消费端消息可靠性保证:
-
消息确认(Acknowledgements):
- 手动应答:代码冗余多,容易出现死循环。
- 自动应答:开启重试功能,发生错误时重新发送,可配置死信队列,重试一定次数后放入死信队列。
-
死信队列(Dead Letter Queue):
RabbitMQ中如何解决消息堆积问题?
解决消息堆积有三种种思路:
- 扩大队列容积,提高堆积上限,采用惰性队列
- 在声明队列的时候可以设置属性x-queue-mode为lazy,即为惰性队列
- 基于磁盘存储,消息上限高
- 性能比较稳定,但基于磁盘存储,受限于磁盘I0,时效性会降低
- 增加更多消费者,提高消费速度(不能保证有序性)
- 在消费者内开启线程池加快消息处理速度(不能保证有序性)
RabbitMQ中如何保证消息有序性?
单个队列与单一消费者:
- 单个队列:将所有需要保持有序的消息发送到同一个队列中。RabbitMQ的队列是先进先出(FIFO)的数据结构,消息在被发送到队列之后,会按照发送的顺序被排列在队列中。
- 单一消费者:确保该队列只被一个消费者(单线程)处理。这样,消费者会按照队列中的顺序接收到消息,并依次处理,从而保证了消息的顺序性。
如何防止消息重复消费?(如何保证消息幂等性)
幂等性指的是一个操作无论执行多少次,其结果都是相同的。
在分布式系统和消息队列中,幂等性特别重要,因为它可以确保即使在消息重复发送或处理过程中出现故障的情况下,系统状态的一致性和数据的完整性。
生产端保证消息的幂等性:
- 状态检查:
在消息发送前,先查询数据库,确认此消息是否已被处理过(一般通过单据状态)。如果是,则直接忽略;否则,继续处理,并在处理完成后更新消息状态为已处理。
消费端保证消息的幂等性:
- 唯一标识:每个消息都携带一个业务ID(BizId),如订单号、交易流水号等,以便在消费端能够识别重复的消息。
相关文章:
Java后端面试题(mq相关)(day9)
目录 为什么用MQ? 异步 、削峰、解耦1. 异步处理2. 解耦3. 削峰填谷 Exchange类型什么是死信队列?如何保证消息的可靠性?RabbitMQ中如何解决消息堆积问题?RabbitMQ中如何保证消息有序性?如何防止消息重复消费?(如何保证消息幂等…...
算法-华为OD机试-识别有效的IP地址和掩码并进行分类统计
1.描述 见牛客网 https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a74356822. 分析 根据题目要求,分为以下几步 1. 提取IP地址和子网掩码 我们首先需要拆分输入的每一行,分别提取IP地址和子网掩码,并检查它们的合法性。 2.…...
钉钉开发网页应用JSAPI前端授权鉴权nodejs实现
钉钉开发网页应用JSAPI前端授权鉴权nodejs实现 使用钉钉进行H5网页开发的时候,需要调用一些钉钉提供具有原生能力的api,要调用这些api需要进行jsapi授权。 详见官方文档(可选)开发网页应用前端 - 钉钉开放平台 (dingtalk.com) 官方…...
uniapp 自定义全局弹窗
自定义全局弹窗可在js和.vue文件中调用,unipop样式不满足,需自定义样式。 效果图 目录结构 index.vue <template><view class"uni-popup" v-if"isShow"><view class"uni-popup__mask uni-center ani uni-cust…...
element+-ui图片无法使用--安装
element-ui图片无法使用 安装npm install element-plus/icons-vue 注册 // main.jsimport * as ElementPlusIconsVue from element-plus/icons-vueconst app createApp(App) for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, compo…...
Python编码系列—Python ORM(对象关系映射):高效数据库编程实践
🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…...
一次日志记录中使用fastjson涉及到ByteBuffer的教训
背景 目前本人在公司负责的模块中,有一个模块是负责数据同步的,主要是将我们数据产线使用的 AWS Dynamodb 同步的我们的测试QA 的环境的 MongoDB 的库中,去年开始也提供了使用 EMR 批量同步的功能,但是有时候业务也需要少量的数据…...
掌握TCP连接管理与流量控制:从零开始
文章目录 1. TCP连接管理1.1 三次握手(Three-way Handshake)1.2 四次挥手(Four-way Handshake)1.3 TCP连接管理的重要性 2. TCP流量控制2.1 滑动窗口(Sliding Window)2.2 拥塞控制(Congestion C…...
python提取b站视频的音频(提供源码
如果我想开一家咖啡厅,那么咖啡厅的音乐可得精挑细选!又假设我非常喜欢o叔,而o叔只在b站弹钢琴,那这时候我就得想方设法把b站的视频转为音频咯! 一、首先打开网页版bilibili,按F12: 二、刷新页面…...
嵌入式Linux ,QT5 鼠标键盘设备参数指定环境变量的方法
根文件系统中,一般用mdev来管理设备,不像udev方便,有时候在执行rcS脚本的时候因为,太快,有些设备比如鼠标还没在/dev/input中生成设备文件,最好使用前用mdev -s扫描并等待几秒钟,然后就可以在in…...
C语言钥匙迷宫2.0
目录 开头程序程序的流程图程序游玩的效果结尾 开头 大家好,我叫这是我58。废话不多说,咱们直接开始。 程序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <string.h> #include <Windows.h> enum color {Y,B,R …...
【多线程】初步认识Thread类及其应用
💐个人主页:初晴~ 📚相关专栏:多线程 / javaEE初阶 上篇文章我们简单介绍了什么是进程与线程,以及他们之间的区别与联系,实际应用中还是以多线程编程为主的,所以这篇文章就让我们更加深入地去剖…...
algorithm算法库学习之——划分操作和排序操作
algorithm此头文件是算法库的一部分。本篇介绍划分操作和排序操作。 划分操作 is_partitioned (C11) 判断范围是否已按给定的谓词划分 (函数模板) partition 将范围中的元素分为两组 (函数模板) partition_copy (C11) 复制一个范围,将各元素分为两组 (函数模板) st…...
XSS实验记录
目录 XXS地址 实验过程 Ma Spaghet Jeff Ugandan Knuckles Ricardo Milos Ah Thats Hawt Ligma Mafia Ok, Boomer XXS地址 XSS Game - Learning XSS Made Simple! | Created by PwnFunction 实验过程 Ma Spaghet 要求我们弹出一个alert(1337)sandbox.pwnfuncti…...
Cortex-A7的GIC(全局中断控制器)使用方法(7):基于stm32MP135的GIC配置中断效果测试
0 参考资料 STM32MP13xx参考手册.pdf(RM0475) ARM Generic Interrupt Controller Architecture version 2.0 - Architecture Specification.pdf 1 GIC配置中断效果测试 前面我们已经实现了GIC的配置,为了验证GIC是否配置有效,本例…...
c++动态数组new和delete
文章目录 动态数组的使用大全1. **基本创建和初始化**2. **动态调整大小**3. **动态数组的使用与标准库 std::vector**4. **动态数组作为函数参数**输出 5. **使用动态数组存储用户输入** 动态数组的使用大全 1. 基本创建和初始化 示例: #include <iostream&g…...
Redis热点知识速览(redis的数据结构、高性能、持久化、主从复制、集群、缓存淘汰策略、事务、Pub/Sub、锁机制、常见问题等)
Redis是一个开源的、使用内存作为存储的、支持数据结构丰富的NoSQL数据库。它的高性能、灵活性和简单易用使其在许多场景下成为首选的缓存解决方案。以下是Redis的常见和热点知识总结。 数据结构 Redis支持五种基本数据结构: String:字符串是Redis中最…...
【C++浅析】lambda表达式:基本结构 使用示例
基本结构 [捕获列表](参数列表) -> 返回类型 { // 函数体 } 捕获列表 ([ ]): 用于指定外部变量的捕获方式。可以: 通过值捕获:[x]通过引用捕获:[&x]捕获所有变量通过值:[]捕获所有变量通过引用:[&]自…...
利用Redis获取权限的多种方式
更多实战内容,可前往无问社区查看http://www.wwlib.cn/index.php/artread/artid/10333.html Redis是我们在实战中经常接触到的一款数据库,因其在前期打点中被利用后可直接影响服务器安全所以在攻防过程中也备受红队关注,在本文中会重点分享一…...
LeetCode - LCR 146- 螺旋遍历二维数组
LCR 146题 题目描述: 给定一个二维数组 array,请返回「螺旋遍历」该数组的结果。 螺旋遍历:从左上角开始,按照 向右、向下、向左、向上 的顺序 依次 提取元素,然后再进入内部一层重复相同的步骤,直到提取完…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型
在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重,适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解,并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
Spring是如何实现无代理对象的循环依赖
无代理对象的循环依赖 什么是循环依赖解决方案实现方式测试验证 引入代理对象的影响创建代理对象问题分析 源码见:mini-spring 什么是循环依赖 循环依赖是指在对象创建过程中,两个或多个对象相互依赖,导致创建过程陷入死循环。以下通过一个简…...
scan_mode设计原则
scan_mode设计原则 在进行mtp controller设计时,基本功能设计完成后,需要设计scan_mode设计。 1、在进行scan_mode设计时,需要保证mtp处于standby模式,不会有擦写、编程动作。 2、只需要固定mtp datasheet说明的接口即可…...
Amazon RDS on AWS Outposts:解锁本地化云数据库的混合云新体验
在混合云架构成为企业数字化转型标配的今天,如何在本地数据中心享受云数据库的强大能力,同时满足数据本地化、低延迟访问的严苛需求?Amazon RDS on AWS Outposts 给出了完美答案——将AWS完全托管的云数据库服务无缝延伸至您的机房࿰…...
