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,请返回「螺旋遍历」该数组的结果。 螺旋遍历:从左上角开始,按照 向右、向下、向左、向上 的顺序 依次 提取元素,然后再进入内部一层重复相同的步骤,直到提取完…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
