RabbitMQ 常见问题
1. 如何保证消息顺序消费
在RabbitMQ中,消息最终会保存在队列中,在同一个队列中,消息是顺序的,保持先进先出的原则,这个由Rabbitmq保证。而不同队列中的消息,RabbitMQ 是无法保证其顺序性。顺序消费主要是指消费者按照队列中消息出队的顺序消费,出现顺序错乱的场景主要有两种:
- 一个queue存在多个consumer去消费,这样就可能会造成顺序的错乱。虽然consumer从MQ里面读取消息是顺序的,但是每个consumer的执行时间是不固定的,无法保证先读到消息的consumer一定先完成操作,如果先消费的处理时间很长,后面消费的处理时间很快,这样就会出现先出队的消息要晚于后出队的消息执行,从而造成消息顺序错乱。
- 一个quque上只有一个consumer去消费,但是这个consumer是多线程异步处理,因此也不能保证这个consumer按顺序消费;
解决方案:
- 单一队列顺序消费:将所有需要按顺序处理的消息发送到同一个队列中,然后只使用一个消费者单线程去处理消费队列中的消息。这样可以确保消息按照发送的顺序被消费,只是会牺牲消息消费的吞吐量。
- 设置消息序号标识:根据队列中消息的顺序设置一个递增的序号,当消费者消费处理时判断当前消息的序号的前一位是否已存在消息的处理记录表中,不存在说明前面一个消息还未处理完,然后不断轮询记录表中的前一个序号的记录,直到查询到前一个序号的记录之后再执行当前消息的处理逻辑,执行完成后再将当前消息的序号信息存储到记录表中。
2. 如何实现消息延时消费
有些场景需要保证队列中的消息不能立即被消费,需要延长一段时间后再进行消费。正常来说,消息到达队列后并且队列没有消息堆积的情况,只要有消费者监听了这个队列并且消费者是正常运行的,那么消息就会立刻被消费掉。实现这种延时消费的方案有两种:
- 延时队列:RabbitMQ 本身不支持延时队列,但是我们可以通过 RabbitMQ 的插件 rabbitmq-delayed-message-exchange来发生延迟消息。
- 死信队列 + 消息过期:创建一个队列并设置好对应的死信队列,该队列不设置任何消费者。先将消息放到这个队列中,并设置消息过期时间,当消息过期后,就会转存到死信队列中,然后消费者只要监听死信队列就好。
3. 如何解决消息堆积问题
消息的堆积是指在消息队列中,当生产者以较快的速度发送消息,而消费者处理消息的速度较慢或者消费者挂了的时候,导致消息在队列中积累并达到队列的存储上限。解决方案有两种:
- 增加更多消费者,提高消费速度:通过水平扩展消费者的数量,提高消息的处理速度,从而减少消息在队列中的滞留时间。
- 扩大队列容积,提高堆积上限:如果要提升队列容积,只把消息保存在内存中显然是不行的。可以使用惰性队列,惰性队列接收到消息后直接存入磁盘而非内存,消费者要消费消息时才会从磁盘中读取并加载到内存。
4. 如何保证消息的可靠性
4.1 生产者丢失消息:生产者发送消息由于网络等原因并没有发送到RabbitMq,或者消息发送到RabbitMq,但是没有找到指定的交换机或者没有匹配到对应的消息队列时,这时就会造成消息的丢失。
解决方案:
- 消息确认机制:在生产者创建的channel上开启确认模式,并在channel上添加监听,通过回调channel.addConfirmListener()函数来创建一个ConfirmListener。如果Broker收到消息,则会给生产者返回一个应答结果,ConfirmListener监听到broker的应答结果,根据具体的应答结果对消息进行重新发送,或记录日志等后续处理。
- 消息返回机制:对于一些不可达的消息,broker会返回一个信号通知生产端,如果消息可达,则不会返回任何信号。通过在channel上添加channel.addReturnListener()函数来创建一个ReturnListener,用于监听不可达的消息,然后进行后续的处理。
4.2 broker消息中间件自身丢失消息:RabbitMq收到生产者的消息后还没有来得及持久化到磁盘,又或者创建队列没有持久化以及消息并没有设置为持久化,在Mq故障宕机后都会有消息丢失的情况。
解决方案:
- 做持久化设置:在创建队列以及发送消息的时候同时设置队列持久化和消息持久化。
4.3 consumer消费者丢失消息:消费者自动ack配置情况下,业务代码异常或者其他故障消息并没有处理完成也会自动ack,从而导致消息丢失。
解决方案:
- 设置手动确认:消费者在声明队列时,设置autoAck=false,RabbitMQ就会等待消费者显式返回ack信号后才从队列中移去消息。消费者成功处理消息后,手动调用void basicAck(long deliveryTag, boolean multiple)方法通知broker该消息已经消费成功。消息处理失败后,通过回调void basicNack(long deliveryTag, boolean multiple, boolean requeue)方法或者void basicReject(long deliveryTag, boolean requeue)方法通知broker该消息消费失败。
4.4 消费者手动确认过程中异常:消费端在消费消息过程中出现异常,还没能调用basicAck应答,此时消息将变成unacked状态,并且一直处于队列中。
解决方案:
- 进行异常捕获:对消费者业务处理逻辑进行异常捕获,然后在catch里面调用basicNack方法返回消费失败的ack信息给broker。再将消费失败的消息记录到日志或者数据库中,后续人工进行处理。
4.5 无效消息循环重入队列:如果消费端在消费消息过程中捕获异常,并进行basicNack应答,将消息重新放入队列中,可能会出现无效的消息循环入队列的问题。假设消息或者代码本身有bug,每次处理这个消息都会报异常,那消息将一直处于消费——>报异常——>重入队列——>继续消费——>报异常。。。的死循环过程。
解决方案:
- 禁止消息重入队:当捕获到异常的时候,调用basicNack方法时,通过设置requeue参数为false,消息不会重入队消费。再将消费失败的消息记录到日志或者数据库中,后续人工进行处理。
4.6 broker未接收到ack信息:如果消费端消费完后,调用basicAck应答过程中由于网络中断等原因,未能将ack信息发送到broker时,会导致队列中的消息一直处于unacked状态。
解决方案:
- 在声明队列的时候添加死信队列,当broker一直未收到消费者返回的ack确认信息的消息,那么RabbitMQ消息队列就不清楚这条消息到底有没有被消费成功,就会将这条消息存放到死信队列中。后续再由人工去进行处理。
5. 如何防止消息重复消费
如果消息已经被消费者消费了,只是在消费者返回ack确认信息的时候出现异常,导致ack信息未能发送到broker,从而导致RabbitMQ不清楚这条消息到底有没有被消费成功,消息队列可能会在消费者未确认消息时进行重试,导致消息被重复消费。
解决方案:
- 消费端在消费逻辑处理中做好幂等性,保证同一个消息不被消费者重复消费两次。实现消息幂等性的方案:生产者每次发送消息的时候会生成一个全局唯一的id放到信息中,每次消费消息之前根据这个全局id去查询db或者redis中是否存在该id的消息信息,如果有,则说明该消息已经消费过,直接返回不再做后续处理;如果没有,则说明该消息未被消费过,继续进行后续业务处理,处理成功之后再将该全局id插入到bd或者redis中。
相关文章:
RabbitMQ 常见问题
1. 如何保证消息顺序消费 在RabbitMQ中,消息最终会保存在队列中,在同一个队列中,消息是顺序的,保持先进先出的原则,这个由Rabbitmq保证。而不同队列中的消息,RabbitMQ 是无法保证其顺序性。顺序消费主要是…...

阶段二-Day10-日期类
日期类结构: 1.java.util.Date是日期类 2.DateFormat是日期格式类、SimpleDateFormat是日期格式类的子类 Timezone代表时区 3.Calendar是日历类,GregorianCalendar是日历的子类 一. 常用类-Date 1.1 Date构造方法 Date(long date) 使用给定的毫秒时间价值构建…...

多任务并行处理相关面试题
我自己面试时被问过两次多任务并行相关的问题: 假设现在有10个任务,要求同时处理,并且必须所有任务全部完成才返回结果 这个面试题的难点是: 既然要同时处理,那么肯定要用多线程。怎么设计多线程同时处理任务呢&…...

Shell脚本学习笔记
1. 写在前面 工作中,需要用到写一些shell脚本去完成一些简单的重复性工作, 于是就想系统的学习下shell脚本的相关知识, 本篇文章是学习shell脚本整理的学习笔记,内容参考主要来自C语言中文网, 学习过程中,…...

ROS-安装xacro
安装 运行下列命令进行安装,xxxxxx处更改为自己的版本 sudo apt-get install ros-xxxxxx-xacro运行 输入下列命令 roscd xacro如果没有报错,并且进入了xacro软件包的目录,则表示安装成功。 参考: [1]https://wenku.csdn.net/ans…...

为什么说 $mash 是 Solana 上最正统的铭文通证?
早在 2023 年的 11 月,包括 Solana、Avalanche、Polygon、Arbitrum、zkSync 等生态正在承接比特币铭文生态外溢的价值。当然,因铭文赛道过于火爆,当 Avalanche、BNB Chain 以及 Polygon 等链上 Gas 飙升至极值,Arbitrum、zkSync 等…...

安装elasticsearch、kibana、IK分词器、扩展IK词典
安装elasticsearch、kibana、IK分词器、扩展IK词典 后面还会安装kibana,这个会提供可视化界面方面学习。 需要注意的是elasticsearch和kibana版本一定要一样!!! 否则就像这样 elasticsearch 1、创建网络 因为我们还需要部署k…...

Spring中常见的BeanFactory后处理器
常见的BeanFacatory后处理器 先给出没有添加任何BeanFactory后处理器的测试代码 public class TestBeanFactoryPostProcessor {public static void main(String[] args) {GenericApplicationContext context new GenericApplicationContext();context.registerBean("co…...
FPGA LCD1602驱动代码 (已验证)
一.需求解读 1.需求 在液晶屏第一行显示“HELLO FPGA 1234!” 2. 知识背景 1602 液晶也叫 1602 字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵 型液晶模块。它由若干个 5X7 或者 5X11 等点阵字符位组成,每个点阵字符位都可以显示一 个字符,每位之间有一个点距的…...

c++编程要养成的好习惯
1、缩进 你说有缩进看的清楚还是没缩进看的清楚 2、i和i i运行起来和i更快 3、 n%20和n&1 不要再用n%20来判断n是不是偶数了,又慢又土,用n&10,如果n&10就说明n是偶数 同理,n&11说明n是奇数 4、*2和<<…...
后台管理项目的多数据源方案
引言 在互联网开发公司中,往往伴随着业务的快速迭代,程序员可能没有过多的时间去思考技术扩展的相关问题,长久下来导致技术过于单一。为此最近在学习互联网思维,从相对简单的功能开始做总结,比如非常常见的基础数据的…...

视频美颜SDK趋势畅想:未来发展方向与应用场景
当下,视频美颜SDK正不断演进,本文将深入探讨视频美颜SDK的发展趋势,探讨未来可能的方向和广泛的应用场景。 1.深度学习与视频美颜的融合 未来,我们可以期待看到更多基于深度学习算法的视频美颜SDK,为用户提供更高质量…...
C++ const 限定符的全面介绍
C const 限定符的全面介绍 1. const 修饰基本数据类型 定义 const 修饰的基本数据类型变量,值不可改变。 语法 const type variable value;特点 不可变性,增加代码可读性。 作用 定义不可修改的常量。 使用场景 全局常量、配置项。 注意事项…...

Vue 中的 ref 与 reactive:让你的应用更具响应性(上)
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…...

华为云CCE-集群内访问-根据ip访问同个pod
华为云CCE-集群内访问-根据ip访问同个pod 问题描述:架构如下:解决方法: 问题描述: 使用service集群内访问时,由于启用了两个pod,导致请求轮询在两个pod之间,无法返回正确的结果。 架构如下&am…...

Kasada p.js (x-kpsdk-cd、x-kpsdk-ct、integrity)
提供x-kpsdk-cd的API服务 详细请私信~ 可试用~ V:zhzhsgg 一、简述 integrity是通过身份验证Kasada检测机器人流量后获得的一个检测结果(数据完整性) x-kpsdk-cd 是经过编码计算等等获得。当你得到正确的解决验证码值之后,解码会看到如下图…...
Thinkphp 5框架学习
TP框架主要是通过URL实现操作 http://servername/index.php/模块/控制器/操作/参数/值.. index.php 为入口文件,在 public 目录内的 index.php 文件; 模块在 application 目录下默认有一个 index 目录,这就是一个模块; 而在 index 目录下有一个 contro…...

麒麟云增加计算节点
一、安装基座系统并配置好各项设置 追加的计算节点服务器,安装好系统,把主机名、网络网线(网线要和其他网线插的位置一样)、hosts这些配置好,在所有节点的/etc/hosts里面添加信息 在控制节点添加/kylincloud/multinod…...

使用Redis进行搜索
文章目录 构建反向索引 构建反向索引 在Begin-End区域编写 tokenize(content) 函数,实现文本标记化的功能,具体参数与要求如下: 方法参数 content 为待标记化的文本; 文本标记的实现:使用正则表达式提取全小写化后的…...
Oracle修改用户密码
文章目录 Oracle修改用户密码Oracle用户锁定常见的两种状态Oracle用户锁定和解锁 Oracle修改用户密码 使用sys或system使用sysdba权限登录,然后执行以下命令修改密码: alter user 用户名 identified by 密码;密码过期导致的锁定,也通过修改…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...