四种途径提高RabbitMQ传输消息数据的可靠性(一)

RabbitMQ(一):消息队列MQ 流量消峰:当流量超过处理上限时,正常情况下,超过上限的流量不做处理。而MQ可以把多出来的一部分流量放入消息队列做缓冲。举个例子:假设某订单系统每秒最多能处理一万次订单,也就是最多承受的10000qps,正常情况下,下单一秒后就能返回结果。但是在高峰期,如果有两万次下单操作,系统是处理不了的,只能限制订单超过一万后不允许用户下单。 阅读详情

前言

RabbitMQ虽然有对队列及消息等的一些持久化设置,但其实光光只是这一个是不能够保障数据的可靠性的,下面我们提出这样的质疑:

(1)RabbitMQ生产者是不知道自己发布的消息是否已经正确达到服务器呢,如果中间发生网络异常等情况呢?消息必然会丢失!

(2)RabbitMQ如果没有设置队列持久化,RabbitMQ服务器重后队列的元数据会丢失,消息自然也会丢失!

(3)RabbitMQ如果消费者设置自动确认,即autoAck为true,那么不管消费者发生什么情况,该消息会自动从队列中移除,实际上消费者有可能挂掉,消息必然会丢失!

(4)RabbitMQ中的消息如果没有匹配到队列时,那么消息也会丢失!


一、设置mandotory参数、AE备份交换器

针对前言中的第(4)个问题,我们可以通过设置mandotory参数与AE备份交换器来解决

1、mandotory参数

1)当为true时,交换器无法根据自身的类型和路由键找到一个符合条件的队列,此时RabbitMQ会调用Basic.Return命令将消息返回给生产者,消息将不会丢失

2)当为false时,消息将会被直接丢弃。

3)RabbitMQ通过addReturnListener添加ReturnLisener监听器监听获取没有被正确路由到合适队列的消息。

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

channel.basicPublish(EXCHANGE NAME, "", true, MessageProperties.PERSISTENT_TEXT_PLAIN, "mandatory test".getBytes()); 
channel.addReturnListener(new ReturnListener(){ 
  public void handleReturn(int replyCode, String replyText, 
                String exchange, String routingKey, 
                AMQP.BasicProperties basicProperties, 
                byte[] body) throws IOException { 
    String message = new String(body); 
    System.out.println("Basic.Return 返回的结果是: " + message);
  }
}); 

2、AE备份交换器

Alternate Exchange,简称AE,不设置mandatory参数,那么消息将会被丢失,设置mandatory参数的话,需要添加ReturnListner监听器,增加复杂代码,如果既不想增加代码又不想消息丢失,则使用AE,将没有被路由的消息存储于RabbitMQ中。当mandatory参数用AE一起使用时,mandatory将失效。在介绍AE之前,也认识RabbitMQ对于消息的过期时间TTL设置以及队列的过期时间TTL设置

2.1 TTL过期时间设置

可以对队列设置TTL与消息设置TTL,其中消息设置TTL经常用于死信队列、延迟队列等高级应用中。

1)设置消息TTL

  设置TTL过期时间一般有两种当时:一是通过队列属性,对队列中所有消息设置相同的TTL。二就是对消息本身单独设置,每条消息TTL不同。如果一起使用时候,TTL小的为准,当一旦超过设置的TTL时间时,就会变成“死信”。

方式一:针对每条消息设置TTL是通过增加expiration的属性参数实现的,不可能像方式二一样扫描整个队列再判断是否过期,只有当该消息即将被消费时再判定是否过期即可删除,也就是消息即使已经过期,但不一定立马被删除!

AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder(); 
// 持久化消息
builder deliveryMode(2);
// 设置 TTL=60000ms
builder expiration( 60000 ); 
AMQP.BasicProperties properties = builder. build(); 
channel.basicPublish(exchangeName, routingKey, mandatory, properties, "ttlTestMessage".getBytes());

方式二:通过队列属性设置消息TTL是增加x-message-ttl参数实现的,只需要扫描整个队列头部即可立即删除,也就是消息一旦过期就会被删除!

Map<String, Object> argss = new HashMap<String , Object>(); 
argss.put("x-message-ttl", 6000); 
channel.queueDeclare(queueName, durable, exclusive, autoDelete, argss) ;

2)设置队列TTL

通过在队列中添加参数x-message-ttl参数实现,设置队列被自动删除前处于未被使用状态的时间,注意是队列的使用状态,并不是消息是否被消费的状态

设置ttl=30min的队列,时间一到RabbitMQ会保证队列被删除,但是不会保证删除的速度有多快。

Map<String, Object> args = new HashMap<String, Object>{); 
args.put("x-expires", 1800000);
channel.queueDeclare("myqueue", false, false, false, args);

2.2 AE备份交换器的使用

声明交换器的时候,添加alternate-exchange参数实现,或通过策略实现。前者优先级高。从代码角度需要以下三个步骤,具体代码如下:

Map<String, Object> args = new HashMap<String, Object>(); 
args.put("a1ternate-exchange", "myAe"); 
channe1.exchangeDec1are("norma1Exchange", "direct", true, fa1se, args); 
channe1.exchangeDec1are("myAe", "fanout", true, fa1se, nu11) ; 
channe1.queueDec1are( "norma1Queue", true, fa1se, fa1se, nu11); 
channe1.queueB nd("norma1Queue", "norma1Exchange", "norma1Key"); 
channe1.queueDec1are("unroutedQueue", true, fa1se, fa1se, nu11);

1)声明normalExchange类型为direct的交换器、类型为fanout的myAe备份交换器;并且normalExchange的备份交换器为myAe(备份交换器建议使用fanout类型交换器)

2)声明normalQueue队列,声明unrouteQueue队列;

3)通过路由键normalKey绑定normalExchange与normalQueue,不适用路由键绑定unrouteQueue与myAe

四种途径提高RabbitMQ传输消息数据的可靠性(一)

 

二、消费者手动确认

针对前言中第(3)个问题,我们需要在消费者消费完消息后手动进行确认,保证消息数据不丢失!

1、autoAck参数设置

1) 当autoAck参数为false时,手动确认:

RabbitMQ会等待消费者显式地回复确认信号后从内存中移去消息(实际上是先标示删除标记,之后再删除),这是一般推荐使用的方式,因为使用手动确认有足够的时间处理消息,不需要担心消费者进程挂掉之后消息丢失问题。此时的消息就会分为两个部分:一是等待投递给消费者的消息;二是已经投递给消费者但还没有收到消费者确认信号的消息。

2) 当autoAck为true时,自动确认:

RabbitMQ会自动隐式地回复确认信号后从内存中移去消息, RabbitMQ不需要管消费者是否真正消费了这些消息,RabbitMQ会自动把发送出去的消息置为确认,然后直接从内存中删除。

2、重新投递

问:如果选择手动确认,即autoAck为false时,消费者由于某些原因断开了,那么消息的确认会受到影响,那么此时的消息会丢失吗?

这也就是一开始提出来的问题,其实是不必担心消息会被丢失,因为RabbitMQ如果一直没收到消费者的确认信号,并且消费此消息的消费者已经断开,则RabbitMQ会重新安排消息进入队列等待给下一个消费者。也就是RabbitMQ不会设置消息的过期时间(当然也可以设置过期时间,但与之有关系方式消息丢失的特性是死信队列),它只判断是否需要重新安排入队列重新投递,而判断的唯一标准是消费此消息的消费者连接是否已经断开,即RabbitMQ会允许消费一条消息的时间很久很久。

3、消费者拒绝消息

1)使用channel.basicReject方法,但只能拒绝一条。

void basicReject(long deliveryTag, boolean requeue) throws IOException;

deliveryTag:消息的唯一标识

requeue:表示是否可以拒绝的消息重新存入队列

 2)使用channel.basicNack。不同于前者,此方法可以批量拒绝。

void basicNack(long deliveryTag, boolean multiple , boolean requeue) throws IOException;

multiple:设置为true则表示拒绝deliveryTag编号之前所有未被当前消费者确认的消息。

3)问:关键在于,消费者拒绝消费消息后怎么处理?是丢弃,还是重新回到队列呢?

当参数requeue设置为true时候,可以重新进入队列,投递给下一个消费者。如果为false,消息就会把队列中消息立马移除,再结合启用“死信队列”,防止消息丢失并且可以分析异常情况的发生。


最后,由于剩下的两种方式涉及的内容较多,所以在此将分成两篇继续介绍,请看下篇

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

RabbitMQ系列教程三:RabbitMQ最全特性一览及Java Api的使用 RabbitMQ入门教程 当初我学RabbitMQ的时候,第一时间就上GitHub找相应的教程,但是令我很失望的是没有找到,Spring,Mybatis之类的教程很多,而RabbitMQ的教程几乎找不到,看的最多的就是朱小厮大佬的博客。后来想着索性自己总结一下吧,有不恰当的地方欢迎小伙伴指出。 这篇文章主要是对着我在GitHub上的源码解释的,因此本文并没有太多的源码。写了挺长时间的,为了防止迷... 阅读详情

相关推荐

告别F5失灵!手把手教你为Cursor配置.Net Core控制台项目专属调试环境

本文详细指导如何在Cursor编辑器中为.Net Core控制台项目配置专属调试环境,解决F5失灵等常见问题。从调试器选择到launch.json配置,再到高级调试技巧,帮助开发者高效搭建完整的调试工具链,提升开发效率。

weixin_28834765的博客 288

RabbitMQ — 消息确认机制解析

对于某些消息而言,我们有时候需要严格的知道消息是否已经被 consumer 监听消费处理了,即我们有一种消息确认机制来保证我们的消息是否已经真正的被消费处理。在 RabbitMQ 中,消息确认处理机制有三种:Auto - 自动、Manual - 手动、None - 无需确认,而确认机制需要 listener 实现 ChannelAwareMessageListener 接口,并重写其中的确认消费逻辑。 1. 自动确认 AcknowledgeMode.NONE RabbitMQ成功将消息发出(即将消息成功写

qq_38658567的博客 1408

高德地图JS API私有化部署实战:从数据爬取到内网集成

本文详细介绍了高德地图JS API私有化部署的完整流程,涵盖从地图瓦片数据爬取、JS API离线化改造到内网项目集成的实战步骤。重点解决了在封闭内网环境中实现地图功能的核心难题,并提供了Vue.js项目中的具体集成代码与调试技巧,帮助开发者在离线环境下构建稳定可靠的地图应用。

weixin_29062255的博客 319

Rabbitmq的消息确认机制(十一)

一、前言 RabbitMq提供了消息确认机制,主要分为生产者端发送消息确认和消费者端的消费消息确认。 生产者端发送消息确认又分为Confirm 消息确认机制和Return 消息机制; 消费者端 则分为Ack 和 Nack 机制。 二、生产者端消息确认机制 1.1 引入 rabbitmq 依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"

weixin_41979002的博客 3280

STM32 HAL库定时器中断里读编码器速度准吗?聊聊MG310电机的测速与防溢出处理

本文探讨了STM32 HAL库在定时器中断中读取编码器速度的精度问题,特别针对MG310电机的测速与防溢出处理提供了解决方案。通过对比定时中断法和编码器模式的性能,揭示了硬件编码器接口在降低误差和CPU占用率方面的优势,并详细介绍了CubeMX配置技巧和防溢出处理的工程实践。

weixin_28720767的博客 401

公交车调度排班优化算法研究与实现

本文提出的公交车调度排班优化算法基于遗传算法,能够较好地处理公交车调度排班问题,使得车辆数量和运营时间得到平衡,公交车的使用效率得到了优化。在模拟的公交车路线中,使用本文所提出的算法,得到了一组较优的公交车调度排班方案。其中,车辆数量的多少会影响到公交车的行驶速度和等候时间,而运营时间的长短则会直接影响到公交车的使用效率和成本。本文基于遗传算法,通过随机生成种群、选择、交叉、变异等操作,逐步优化种群中个体的适应度,最终得到较优的公交车调度排班方案。以下是本文中所使用的Matlab代码实现,供参考。

PixelLoom的博客 872

【RabbitMQ】RabbitMQ如何确认消息被消费、以及保证消息的幂等

消费者消费成功后会给MQ服务器的队列发送一个确认消息,此时会有一个回调检测服务监听该接收确认消息的队列,然将消费的消息写入数据库。以上是消息成功被消费时的流程,此时如果消费者没有将消息消费,就不会给服务器发送确认消息了,生产者隔一段时间会延迟发送与之前发送的一模一样的数据到另一个给回调检测服务监听的队列,该服务收到延迟发送的消息后就会去数据库的消息表查询是否有该条消息,但是由于消费者没有消费成功给RabbitMQ服务器发送确认消息,所以数据库里并没有该消息,此时就会让生产者重新发送该消息。

qq_61903414的博客 3309

[Dify实战] 招聘筛简历机器人:自动筛选、排序、生成面试要点-带绑定资源

摘要:本文介绍了如何利用Dify优化简历筛选流程,解决人工筛选耗时、标准不统一等问题。通过结构化输出"评分+亮点+风险+面试关注点",将主观判断转化为规则化流程。关键步骤包括:设计标准化Prompt、配置权重排序策略、确保公平合规性、与ATS系统对接,以及持续优化评估指标。该方法能显著提升筛选效率(缩短招聘周期)、增强一致性(避免主观偏差),并为面试官提供结构化参考信息,最终实现更高效精准的人才筛选。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 581

rabbitmq怎样确认是否已经消费了消息_【RabbitMq 篇六】消息确认(发送确认与接收确认)...

前言消息确认是保证消息传递可靠性的重要步骤,上一节我们说到持久化,持久化只能保证消息不丢失,但是如果消息如果投递失败我们怎么进行补偿操作呢?解决办法就是实现回调函数进行操作,在消息的发送和消息的消费都可以进行补偿操作,下面我们就要讲解消息确认。正文目录前言正文消息确认种类消息发送确认ConfirmCallbackReturnCallback消息消费确认消息确认种类消息的确认做有很多法,其...

weixin_39641236的博客 2815

基于FPGA的7x7矩阵求逆verilog开发

up目录一、理论基础二、核心程序三、测试结果 矩阵求逆,即求矩阵的逆矩阵。矩阵是线性代数的主要内容,很多实际问题用矩阵的思想去解既简单又快捷。逆矩阵又是矩阵理论的很重要的内容,逆矩阵的求法自然也就成为线性代数研究的主要内容之一。设A是数域上的一个n阶方阵,若在相同数域上存在另一个n阶矩B,使得: AB=BA=E。 则我们称B是A的逆矩阵,而A则被称为可逆矩阵。其中,E为单位矩阵。典型的矩阵求逆方法有:利用定义求逆矩阵、初等变换法、伴随阵法、恒等变形法等。 逆矩阵的求法有多种,其中重要

FPGA/MATLAB学习教程/源码/项目合作开发 3898

Unity 热更新技术 |(六)xLua框架学习最新系列完整教程

开始学习热更新方面系列知识,就从这一篇开始吧! 本系列教程 会从热更新基本概念出发,详细介绍热更新相关的全套知识点。 如热更新技术基本原理、热更新主流方案、AssetBundle系列教程、Lua语言编程、Lua与Unity交互教程、Xlua框架使用、热更新实战教程等方面。 热更新作为一个开发者必备技能,如果想学习的话,可以从现在开始了哦~ 接下来先从XLua学习使用 开始学习吧!

努力前行,总会成为自己心中的那道光 1万+

rabbitmq可靠性投递_四种途径提高RabbitMQ传输消息数据的可靠性(一)

四种途径提高RabbitMQ传输消息数据的可靠性(一)发布时间:2019-02-22 16:11,浏览次数:1221, 标签:RabbitMQ前言RabbitMQ虽然有对队列及消息等的一些持久化设置,但其实光光只是这一个是不能够保障数据的可靠性的,下面我们提出这样的质疑:(1)RabbitMQ生产者是不知道自己发布的消息是否已经正确达到服务器呢,如果中间发生网络异常等情况呢?消息必然会丢失!(2)...

weixin_39580749的博客 129

华为OD机考双机位C卷 - 构成正方形的数量 (Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 成正方形的数量 (OD上机考试双机位C卷)。提供在线OJ刷题。Java、C++、Python、GO语言、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 5939

rabbitmq怎样确认是否已经消费了消息_四种途径提高RabbitMQ传输消息数据的可靠性(一)...

前言RabbitMQ虽然有对队列及消息等的一些持久化设置,但其实光光只是这一个是不能够保障数据的可靠性的,下面我们提出这样的质疑:(1)RabbitMQ生产者是不知道自己发布的消息是否已经正确达到服务器呢,如果中间发生网络异常等情况呢?消息必然会丢失!(2)RabbitMQ如果没有设置队列持久化,RabbitMQ服务器重后队列的元数据会丢失,消息自然也会丢失!(3)RabbitMQ如果消费者设置自...

weixin_39575758的博客 1702

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

四种途径提高RabbitMQ传输数据的可靠性(二)

前言 上一篇四种途径提高RabbitMQ传输消息数据的可靠性(一)已经介绍了两种方式提高数据可靠性传输的方法,本篇针对上一篇中提出的问题(1)与问题(2)提出解决常用的方法。 本文其实也就是结合以上四个方面进行讲解的,主要参考《RabbitMQ实战指南》(有需要PDF电子书的可以评论或者私信我),本文截图也来自其中,另外可以对一些RabbitMQ的概念的认识可以参考我的另外两篇博文认识R...

weixin_30329623的博客 132

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

rabbitmq 手动提交_四种途径提升RabbitMQ传输消息数据的可靠性(一)

前言一、设置mandotory参数、AE备份交换器针对前言中的第(4)个问题,我们可以通过设置mandotory参数与AE备份交换器来解决1、mandotory参数1)当为true时,交换器无法根据自身的类型和路由键找到一个符合条件的队列,此时RabbitMQ会调用Basic.Return命令将消息返回给生产者,消息将不会丢失2)当为false时,消息将会被直接丢弃。3)RabbitMQ通过add...

weixin_39702335的博客 336

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

四种途径提升RabbitMQ传输数据的可靠性

前言 RabbitMQ虽然有对队列及消息等的一些持久化设置,但其实光光只是这一个是不能够保障数据的可靠性的,下面我们提出这样的质疑: (1)RabbitMQ生产者是不知道自己发布的消息是否已经正确达到服务器呢,如果中间发生网络异常等情况呢?消息必然会丢失! (2)RabbitMQ如果没有设置队列持久化,RabbitMQ服务器重后队列的元数据会丢失,消息自然也会丢失! (3)Rabbit...

weixin_30885111的博客 123

mq集群要建传输队列吗_四种途径提升RabbitMQ传输数据的可靠性(二)

前言上一篇四种途径提高RabbitMQ传输消息数据的可靠性(一)已经介绍了两种方式提高数据可靠性传输的方法,这一篇继续针对上一篇中提出的问题(1)与问题(2)提出解决常用的方法,三、生产者确认机制针对问题(1),我们可以通过生产者的确认消息机制来解决,主要分为两种:第一是事务机制、第二是发送方确认机制1、事务机制与事务机制相关的有三种方法,分别是channel.txSelect设置当前信道为事务模...

weixin_39913807的博客 111

《RabbitMQ 实战指南》第五章 RabbitMQ 进阶(下)

《RabbitMQ 实战指南》第五章 RabbitMQ 进阶(下)

2022年毕业的萌新程序猿,输出一下自己的学习内容~ 1645

消息中间件基础知识-从RabbitMQ、RocketMQ、Kafka到Pulsar

本文梳理笔者的MQ知识,从消息中间件的基础知识讲起,在有了基础知识后,对市面上各主流的消息中间件进行详细的解析,包括 RabbitMQ、RocketMQ、Kafka、Pulsar,最后再横向对比这几款主流的消息中间件。

qq_25808483的博客 811

解决RabbitMQ消息丢失与重复消费问题

解决RabbitMQ消息丢失与重复消费问题 想想为什么要使用MQ? 1.解耦,系统A在代码中直接调用系统B和系统C的代码,如果将来D系统接入,系统A还需要修改代码,过于麻烦! 2.异步,将消息写入消息队列,非必要的业务逻辑以异步的方式运行,加快响应速度 3.削峰,并发量大的时候,所有的请求直接怼到数据库,造成数据库连接异常 使用了消息队列会有什么缺点? 1.系统可用性降低:你想啊,本来其他系统只要运行好好的,那你的系统就是正常的。现在你非要加个消息队列进去,那消息队列挂了,你的系统不是呵呵了。因此,系统可用

weixin_43564627的博客 2778
上一篇: 不改一行代码定位线上性能问题
下一篇: 四种途径提高RabbitMQ传输数据的可靠性(二)
javaQQ群 866865133
博客等级 码龄8年 59粉丝 309原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值