RabbitMq 的消息可靠性问题(二)---MQ的消息丢失和consumer消费问题

news2024/11/24 18:36:02

前言

在这里插入图片描述
RabbitMq 消息可靠性问题(一) — publisher发送时丢失
前面我们从publisher的方向出发解决了发送时丢失的问题,那么我们在发送消息到exchange, 再由exchange转存到queue的过程中。如果MQ宕机了,那么我们的消息是如何确保可靠性的呢?当消息由队列发到对应的消费者处理时,consumer 接受到消息未消费就宕机,这时消息又如何确保可靠性呢?

消息可靠性问题及其对应的解决方案:

场景publisher发送时丢失MQ消息丢失consumer消费问题
解决方案生产者确认机制消息持久化消费者消息确认&&失败重试机制

消息持久化

MQ 默认是内存存储信息, 开启持久化功能可以确保缓存在 MQ 中的消息不丢失

  1. 交换机持久化
@Bean
public DirectExchange simpleDirect(){
	// 三个参数:交换机名称, 是否持久化, 当没有queue 与其绑定时是否自动删除
	return new DirectExchange("simple.direct", true, false);
}
  1. 队列持久化
@Bean
public Queue simpleQueue(){
	// 使用QueueBuilder构建队列,durable就是持久化的
	return QueueBuilder.durable("simple.queue").build();
}
  1. 消息持久化,SpringAMQP 中的消息默认是持久化, 可以通过MessagePropertie中的DeliveryMode 来指定的
@Test
public void testDurableMessage(){
	// 1. 准备消息
	Message message = MessageBuilder.withBody("hello,spring".getBytes(StandardCharsets.UTF_8))
			  .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
			  .build();
	// 2. 发送消息
	rabbitTemplate.convertAndSend("simple.queue", message);
}

其实,默认情况下 SpringAMQP 中的交换机,队列,消息都是持久化的
(所以上诉的持久化参数和代码只需要了解即可)

消费者消息确认

RabbitMQ 支持消费者确认机制,即:消费者处理消息后可以向MQ 发送ack回执。MQ收到 ack 回执后才删除该消息。而SpringAMQP 则允许配置三种确认模式:

  • manual:手动 ack, 需要在业务代码结束后,调用 api 发送ack

  • auto: 自动 ack, 由Spring检测 listener 的代码是否出现异常,没有异常则返回 ack; 抛出异常则返回 nack

  • none: 关闭 ack, MQ 假定消费者获取消息后成功处理,因此消息投递后立即删除

在 consumer 服务的 application,yml 中进行如下配置:

spring:
	rabbitmq:
		listener:
		  simple:
			prefetch: 1
			acknowledge-mode: auto

失败重试机制

消费者失败重试
当消费者出现异常后,消息会不断 requeue(重新入队)到队列,再重新发送给消费者,然后再次异常,再次 requeue, 无限循环,导致 mq 的消息处理飙升,带来不必要的压力
在这里插入图片描述
我们可以利用 Spring 的 retry 机制,在消费者出现异常先利用本地重试,而不是无限的 requeue 到 mq 的队列。

可在 yml 的文件中进行如下配置:

spring:
	rabbitmq:
		listener:
			simple:
				prefetch: 1
				retry: 
					enabled: true # 开启消费者失败重试
					initial-interval: 1000 # 初始失败等待时长为 1s
					multiplier: 3 # 下次失败等待时长的倍数, 下次等待时长= multiplier * last-interval
					max-attempts: 4 # 最大重试次数

消费者失败消息处理策略
在开启重试模式后,重试次数耗尽,如果消息依然失败,则需要有MessageRecoverer 接口来处理,它包含三种不同实现:

  • RejectAndDontRequeueRecoverer:重试耗尽后,直接 reject, 丢弃消息。默认就是这种方式
  • ImmediateRequeueMessageRecoverer: 重试耗尽后,返回 nack, 消息重新入队
  • RepublishMessageRecoverer: 重试耗尽后,将失败消息投递到指定交换机

在这里插入图片描述
下面简单说明一下 RepublishMessageRecoverer 处理模式

  1. 首先,定义接收失败消息的交换机,队列及其绑定关系:
@Bean
public DirectExchange errorMessageExchange(){
	return new DirectExchange("error.direct");
}
@Bean
public Queue errorQueue(){
	return new Queue("error.queue");
}
@Bean
public Binding errorMessageBinding(){
	return BindingBuilder.bind(errorQueue()).to(errorMessageExchange()).with("error");
}
  1. 定义 RepublishMessageRecoverer
@Bean
public MessageRecoverer republishMessageRecoverer(RabbitTemplate rabbitTemplate)
{
	return new RepublishMessageRecoverer(rabbitTemplate, "error.direct","error");
}

进行完上面的配置后,我们在消费者处理消息异常后,会进行一个本地的重试。而不是直接 requeue 到队列中。
当我们重试次数耗尽后,我们会把错误消息投递到 error.direct 的交换机上,然后在 error.queue上进行转存。这样既能减轻 mq 的压力,也能在队列上找到处理异常的消息,进行人工介入处理。

总结

如何确保 RabbitMQ 消息的可靠性?

  • 开启生产者确认机制,确保生产者的消息能到达队列
  • 开启持久化功能,确保消息未消费在队列中不会丢失
  • 开启消费者确认机制为 auto, 由 spring 确认消息处理成功后完成 ack
  • 开启消费者失败重试机制,并设置 MessageRecoverer, 多次重试失败后将消息投递到异常交换机,交由人工处理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/417874.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SQL的函数

文章目录一、SQL MIN() Function二、SQL SUM() 函数三、SQL GROUP BY 语句四、SQL HAVING 子句五、SQL EXISTS 运算符六、SQL UCASE() 函数总结一、SQL MIN() Function MIN() 函数返回指定列的最小值。 SQL MIN() 语法 SELECT MIN(column_name) FROM table_name;演示数据库 …

Numba witch makes Python code fast

一. 前言:numba,让python速度提升百倍 python由于它动态解释性语言的特性,跑起代码来相比java、c要慢很多,尤其在做科学计算的时候,十亿百亿级别的运算,让python的这种劣势更加凸显。 办法永远比困难多&a…

ASP.NET Core MVC 从入门到精通之接化发(二)

随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生&#xff0c…

4.13实验 加测试题目

今天是个好日子,要搞栈的实验 没啥就是链栈和顺序栈 和出栈入栈,强大都是从最基本开始的 来和我一起写写吧 //顺序栈 typedef struct node{int *base;int *top;int sizer; }shed;//链栈 typedef struct Node{ int data; struct Node* next; }*stact,link; //顺序栈的初始化…

《绝对坦率》速读笔记

文章目录书籍信息概览(第一部分 一种新的管理哲学)建立坦率的关系给予并鼓励指导了解团队中每个人的动机协同创造成果(第二部分 工具和技巧)关系指导团队结果书籍信息 书名:《绝对坦率:一种新的管理哲学》…

北邮22信通:(12)二叉树的遍历书上代码完整版

北邮22信通一枚~ 跟随课程进度每周更新数据结构与算法的代码和文章 持续关注作者 解锁更多邮苑信通专属代码~ 上一篇文章: 下一篇文章: 目录 一.储存最简单数据类型的二叉树 代码部分: 代码效果: 运行结果&#xff1a…

解决JD-GUI-1.6.6 中文乱码

一、背景 在window环境下使用中遇到了乱码问题。 问题有两个: 一、从反编译代码的界面 CTRLC 复制是如果选中内容包含中文,贴到其他编辑器时,中文丢失。 二、打开xml文件、properties文件等包含中文时。中文在反编译界面中显示乱码。用其他工…

java反射教程

反射(Reflection)是 Java中的一种机制,它是一种特殊的面向对象编程技术。在 Java中,反射可以分为静态反射和动态反射两种。静态反射是指在 Java程序运行时才进行的一种反射,它可以保证程序运行时不会出现内存泄漏等错误…

数据分析的作用和意义?

数据分析的作用和意义?在当下数字化转型发展的大环境中,数据也成为企业商业成功与否的重要基础,如何利用好数据分析问题预测未来也成为更多企业面临的首要问题。而随时大数据的不断渗透,数据量和数据类型也越来越多,数…

asp.net车辆管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net车辆管理系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言开发 asp.net车辆管理系统VS开发sqlserver数…

【CSIG图像图形技术挑战赛-开放世界目标检测竞赛】火热报名中!

竞赛名称:开放世界目标检测竞赛/Few Shot)主办方: 中国图象图形学学会(CSIG)合作方: 360集团竞赛目的与意义:目标检测是计算机视觉中的核心任务之一,主要目的是让计算机可以自动识别图片中目标的类别&#…

Windows File Recovery使用教程

Windows File Recovery简介 Windows File Recovery是微软在2020年发布的命令提示符文件恢复工具,它不仅具有高成功率和高安全性,还适用于不同的文件系统和文件丢失场景。如果你需要从本地硬盘、USB设备、SD卡等设备中恢复意外丢失或删除的JPEG、PDF、…

分析Spring事务管理原理及应用

目录 一、Spring事务管理介绍 (一)基本理论 (二)实际工作中的举例 (三)简单应用举例 二、Spring事务配置介绍 (一)Spring事务属性介绍 传播属性(传播行为&#xff…

车身控制模块BCM(Body Control Module)

1.BCM概述 车身控制模块BCM是高集成度的芯片。BCM的英文全称是Body Control Module。其控制对象是采用高灵敏度带唤醒及睡眠检测的高频收发器,实现车门车窗遥控上锁与开锁、电动后视镜、中控门锁、玻璃升降装置、车灯(远光灯、近光灯、位置灯、制动灯、转向灯、雾灯…

【RocketMQ】主从模式下的消费进度管理

在【RocketMQ】消息的拉取一文中可知,消费者在启动的时候,会创建消息拉取API对象PullAPIWrapper,调用pullKernelImpl方法向Broker发送拉取消息的请求,那么在主从模式下消费者是如何选择向哪个Broker发送拉取请求的? 进…

【Linux】项目自动化构建工具-make/Makefile

文章目录1.make/Makefile的重要性2.规则及使用使用规则3.Makefile编译多文件1.make/Makefile的重要性 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中&#xf…

2023美赛春季赛Z题模型代码

已经完成模型代码,仅供大家参考,需要更多请看文末 一、问题分析 首先需要收集与奥运会举办城市/国家相关的历史数据。这需要涉及诸如经济、土地利用、人类满意度(包括运动员和观众)、旅行、基础设施建设、环境影响等多个方面。数…

(二)【软件设计师】计算机系统—CPU运算器控制器

文章目录一、CPU1.计算机硬件基本组成(了解)2.中央处理单元(了解)3.CPU组成4.例题二、运算器1.运算器有两个主要功能2.简要介绍运算器中各组成部件的功能三、控制器1.例题2.组成部分四、总结一、CPU 1.计算机硬件基本组成&#x…

让chatGPT当我的老师如何? 通过和chatGPT交互式学习,了解在ES中,一条JSON数据是如何写到磁盘上的

最近一直有一个问题,如鲠在喉。争取早一天解决,早一天踏踏实实的睡觉。 问题是:在ES中,一条JSON数据是如何写入到磁盘上的? 如何解决这个问题?我想到了chatGPT,还有lucene的学习资料。这篇文章&…

港科夜闻|香港科大(广州)创邻图数据联合实验室正式成立

关注并星标每周阅读港科夜闻建立新视野 开启新思维1、香港科大(广州)创邻图数据联合实验室正式成立。未来,香港科大(广州)与「创邻科技」双方将围绕万亿级大图神经网络计算框架、海量数据的时序图处理、分布式原生图数据库事务及性能优化等前沿图技术领域研究展开深…