RabbitMq之消息确认
最近阅读了rabbitmq的官方文档,然后结合之前面试时被问到关于消息队列的问题来探索一下关于消息队列的消息确认机制。
其实消息确认就是消费者确认消息被消费了, 生产者确认消息已经发送到了消息队列中了。
我们知道rabbitmq有四种消息机制,下图是为了我们对消息确认的理解从官网盗了一张工作队列的图如下:

一、 关于消费者确认方面问题
在我们的mq推送了消息给消费者后,我们怎么知道消息被消费者消费了呢?万一消费者没有消费该消息,或者消费者挂了,这消息是不是就永久丢失了,所以根据此有下列几个关于消费者确认的相关问题。同时在这我们也纠正一个常见的误区,mq是推消息到消费者处的而不是消费者去mq中取消息的,然后在mq中消息充足的情况下,mq推消息给消费者不是等消费者消费完一个再推一个,而是根据 prefetch_count参数来决定可以推多个消息到消费者的缓存里面。
问题1: 如果其中一个消费者开始一项漫长的任务,而仅部分完成而死掉,会发生什么情况。使用我们当前的代码,RabbitMQ一旦将消息传递给消费者,便立即将其标记为删除。在这种情况下,如果您杀死一个work,我们将丢失正在处理的消息。我们还将丢失所有发送给该特定工作人员但尚未处理的消息。
答:为了确保消息永不丢失,RabbitMQ支持 消息确认。消费者发送回一个确认(acknowledgement)以告知RabbitMQ已经接收,处理了特定的消息,然后RabbitMQ会去删除这条消息,如果消费者在不发送确认的情况下死亡(其通道已关闭,连接已关闭或TCP连接丢失),RabbitMQ将了解消息未得到充分处理,并将重新排队。如果同时有其他消费者在线,它将很快将其重新分发给另一个消费者。这样,您可以确保即使工人偶尔死亡也不会丢失任何消息
问题2:开启了消息持久化,消息就一定不会丢失吗?
答: 将消息标记为持久性并不能完全保证不会丢失消息。尽管它告诉RabbitMQ将消息保存到磁盘,但是仍有很短的时间RabbitMQ接受了消息但尚未将其保存。另外,RabbitMQ不会对每条消息都执行fsync(2)-它可能只是保存到缓存中,而没有真正写入磁盘。持久性保证并不强,但是对于我们的简单任务队列而言,这已经绰绰有余了。如果您需要更强有力的保证,则可以使用 发布者确认。
在这里补充一个知识:如果mq开启了持久化以后, 生产者把消息推给消息队列, 消息队列会复制一份消息到持久化队列,然后有新线程从持久化队列中把消息持久化到磁盘中。
问题3: 两个消费者同时消费一个队列,是队列分发消息还是消费者去取消息?
答:您可能已经注意到,调度仍然无法完全按照我们的要求进行。例如,在有两名工人的情况下,当有的消息都很重,有的消息消息很轻时,一位工人将一直忙碌而另一位工人将几乎不做任何工作。好吧,RabbitMQ对此一无所知,并且仍将平均分配消息。
问题4: 关于队列大小的注意事项,如果队列满了怎么处理?
答:如果队列满了以后,我们一方面可以增加消费者的数量,很浅显消费者越多消费消息就越快,还有一个是设置消息的过期时间来控制。
这里补充个知识: 当消息过期或者被消费者拒绝并且设置不返回队列中,这消息将加入死信队列。
二、关于生产者确认方面问题
同样的,我们的生产者给mq push消息的时候,我们怎么知道这消息放进了mq里面了呢?所以这引发了mq确认消息的相关问题。
问题1: 发布者确认消息机制是怎样的?
答:首先消息的传递机制是这样,发布者将消息发送到消息队列的exchange中,然后根据exchange的分发规则,分发到制定具体队列,如果开启了持久化,消息会复制一份持久化队列中, 持久化队列在收到消息后会给队列返回ack确认信息, 然后队列给exchange返回确认信息, exchange根据回调函数给发布者返回确认信息,这样发布者确认就算完成了。
当时你知道发布者的确认规则,你是不是立马想到确认要经过这么多个中间人,省略中间的环节行不行勒,哈哈答案是可以的,不过得自己去改造啦,这是性能优化的一项。
问题2:发布者确认的方式有哪几种?
答:有三种确认方式
1)同步确认,消息发出后一直处于阻塞状态等待确认消息,可以设置超时时间,如果超过超时时间则认为消息丢失, 如果超时或者消息确认失败则会抛出异常,我们捕获异常然后选择是重发还是等其他处理方式。
2)批量确认,一次性发出一批消息然后阻塞等待,形式和同步确认相似,有点则是一批确认所以性能上会有很大的提升,缺点是我们不能确认具体发生了什么错误,并且我们得在内存中存储这批消息以确认发送成功的消息和重发失败的消息。
3)异步确认,发送消息后注册一个回调函数,不阻塞线程,在消息确认后会调用回调函数
如果想更详细地了解其机制可以阅读其官方文档,文档中有关于消息确认的具体代码展示,可以更方便地理解其机制。
RabbitMq之消息确认的更多相关文章
- Java使用RabbitMQ之消息确认(confirm模板)
RabbitMQ生产者消息确认Confirm模式,分为普通模式.批量模式和异步模式,本次举例为普通模式. 源码: package org.study.confirm4; import com.rabb ...
- RabbitMQ的消息确认机制
一:确认种类 RabbitMQ的消息确认有两种. 一种是消息发送确认.这种是用来确认生产者将消息发送给交换器,交换器传递给队列的过程中,消息是否成功投递.发送确认分为两步,一是确认是否到达交换器,二是 ...
- RabbitMq初探——消息确认
消息确认机制 前言 消息队列的下游,业务逻辑可能复杂,处理任务可能花费很长时间.若在一条消息到达它的下游,任务刚处理了一半,由于不确定因素,下游的任务处理进程 被kill掉啦,导致任务无法执行完成.而 ...
- RabbitMQ学习笔记六:RabbitMQ之消息确认
使用消息队列,必须要考虑的问题就是生产者消息发送失败和消费者消息处理失败,这两种情况怎么处理. 生产者发送消息,成功,则确认消息发送成功;失败,则返回消息发送失败信息,再做处理. 消费者处理消息,成功 ...
- RabbitMQ 之消息确认机制(事务+Confirm)
概述 在 Rabbitmq 中我们可以通过持久化来解决因为服务器异常而导致丢失的问题,除此之外我们还会遇到一个问题:生产者将消息发送出去之后,消息到底有没有正确到达 Rabbit 服务器呢?如果不错得 ...
- RabbitMQ (十一) 消息确认机制 - 消费者确认
由于生产者和消费者不直接通信,生产者只负责把消息发送到队列,消费者只负责从队列获取消息(不管是push还是pull). 消息被"消费"后,是需要从队列中删除的.那怎么确认消息被&q ...
- springboot整合rabbitmq,支持消息确认机制
安装 推荐一篇博客https://blog.csdn.net/zhuzhezhuzhe1/article/details/80464291 项目结构 POM.XML <?xml version= ...
- 快速掌握RabbitMQ(三)——消息确认、持久化、优先级的C#实现
1 消息确认 在一些场合,如转账.付费时每一条消息都必须保证成功的被处理.AMQP是金融级的消息队列协议,有很高的可靠性,这里介绍在使用RabbitMQ时怎么保证消息被成功处理的.消息确认可以分为两种 ...
- RabbitMQ的消息确认ACK机制
1.什么是消息确认ACK. 答:如果在处理消息的过程中,消费者的服务器在处理消息的时候出现异常,那么可能这条正在处理的消息就没有完成消息消费,数据就会丢失.为了确保数据不会丢失,RabbitMQ支持消 ...
随机推荐
- 解决alert在ios版微信中显示url的问题(重写alert)
为了解决alert在ios版微信中显示url的问题 window.alert = function(name){ var iframe = document.createElement("I ...
- 数据可视化之powerBI入门(十三)CALCULATE函数的最佳搭档:FILTER
https://zhuanlan.zhihu.com/p/64383000 介绍过CALCULATE函数之后,有必要再介绍它的最佳搭档:FILTER函数. CALCULATE函数的第二个及之后的参数是 ...
- 数据可视化之DAX篇(二十六)Power BI度量值:滚动聚合
https://zhuanlan.zhihu.com/p/85996745 上一篇文讲了累计聚合,这篇文章继续讲一下滚动聚合,比如常用的MAT计算,Moving Annual Total,滚动年度总计 ...
- 迎难而上ArrayList,源码分析走一波
先看再点赞,给自己一点思考的时间,思考过后请毫不犹豫微信搜索[沉默王二],关注这个长发飘飘却靠才华苟且的程序员.本文 GitHub github.com/itwanger 已收录,里面还有技术大佬整理 ...
- Quartz.Net系列(十六):Misfire策略在SimpleScheduler和CronScheduler中的使用
1.场景 ①因为工作线程都在忙碌,所以导致某些Trigger得不到触发 也就是默认10个工作线程而我有15个Trigger同时触发 这就导致有5个不能被触发,而不幸的是Trigger所关联的Job执行 ...
- GPO - Windows Server Update Services
Windows Server Update Services Configuration Wizard: Approve procedure of these updates is very tiri ...
- Android 对接硬件串口篇
简介:硬件设备有IC卡片,指压测试仪(测试脉搏信号.心率.血压),经过串口获取硬件设备发送的数据. 正文:第一步:获得硬件设备,应用市场下载串口调适软件,测试一下在Android环境下数据是否能正常获 ...
- Java实现一个简单的文件上传案例
Java实现一个简单的文件上传案例 实现流程: 1.客户端从硬盘读取文件数据到程序中 2.客户端输出流,写出文件到服务端 3.服务端输出流,读取文件数据到服务端中 4.输出流,写出文件数据到服务器硬盘 ...
- 05 . ELK Stack+Redis日志收集平台
环境清单 IP hostname 软件 配置要求 网络 备注 192.168.43.176 ES/数据存储 elasticsearch-7.2 内存2GB/硬盘40GB Nat,内网 192.168. ...
- three.js 数学方法之Matrix3
今天郭先生来说一说three.js的三维矩阵,这块知识需要结合线性代数的一些知识,毕业时间有点长,线性代数的知识大部分都还给了老师.于是一起简单的复习了一下.所有的计算都是使用列优先顺序进行的.然而, ...