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,请返回「螺旋遍历」该数组的结果。 螺旋遍历:从左上角开始,按照 向右、向下、向左、向上 的顺序 依次 提取元素,然后再进入内部一层重复相同的步骤,直到提取完…...

Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南
在RK3588上搭建ROS1环境:创建节点与数据可视化实战指南 背景介绍完整操作步骤1. 创建Docker容器环境2. 验证GUI显示功能3. 安装ROS Noetic4. 配置环境变量5. 创建ROS节点(小球运动模拟)6. 配置RVIZ默认视图7. 创建启动脚本8. 运行可视化系统效果展示与交互技术解析ROS节点通…...

门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...