RabbitMQ - Publisher的消息确认机制
queue和consumer之间的消息确认机制:通过设置ack。那么Publisher能不到知道他post的Message有没有到达queue,甚至更近一步,是否被某个Consumer处理呢?毕竟对于一些非常重要的数据,可能Publisher需要确认某个消息已经被正确处理。
1. 事务机制 VS Publisher Confirm
如果采用标准的 AMQP 协议,则唯一能够保证消息不会丢失的方式是利用事务机制 -- 令 channel 处于 transactional 模式、向其 publish 消息、执行 commit 动作。在这种方式下,事务机制会带来大量的多余开销,并会导致吞吐量下降 250% 。为了补救事务带来的问题,引入了 confirmation 机制(即 Publisher Confirm)。
为了使能 confirm 机制,client 首先要发送 confirm.select 方法帧。取决于是否设置了 no-wait 属性,broker 会相应的判定是否以 confirm.select-ok 进行应答。一旦在 channel 上使用 confirm.select方法,channel 就将处于 confirm 模式。处于 transactional 模式的 channel 不能再被设置成 confirm 模式,反之亦然。
一旦 channel 处于 confirm 模式,broker 和 client 都将启动消息计数(以 confirm.select 为基础从 1 开始计数)。broker 会在处理完消息后,在当前 channel 上通过发送 basic.ack 的方式对其进行 confirm 。delivery-tag 域的值标识了被 confirm 消息的序列号。broker 也可以通过设置 basic.ack 中的 multiple 域来表明到指定序列号为止的所有消息都已被 broker 正确的处理了。
在异常情况中,broker 将无法成功处理相应的消息,此时 broker 将发送 basic.nack 来代替 basic.ack 。在这个情形下,basic.nack 中各域值的含义与 basic.ack 中相应各域含义是相同的,同时 requeue 域的值应该被忽略。通过 nack 一或多条消息,broker 表明自身无法对相应消息完成处理,并拒绝为这些消息的处理负责。在这种情况下,client 可以选择将消息 re-publish 。
在 channel 被设置成 confirm 模式之后,所有被 publish 的后续消息都将被 confirm(即 ack) 或者被 nack 一次。但是没有对消息被 confirm 的快慢做任何保证,并且同一条消息不会既被 confirm 又被 nack 。
2. 消息在什么时候确认
broker 将在下面的情况中对消息进行 confirm :
- broker 发现当前消息无法被路由到指定的 queues 中(如果设置了 mandatory 属性,则 broker 会先发送 basic.return)
- 非持久属性的消息到达了其所应该到达的所有 queue 中(和镜像 queue 中)
- 持久消息到达了其所应该到达的所有 queue 中(和镜像 queue 中),并被持久化到了磁盘(被 fsync)
- 持久消息从其所在的所有 queue 中被 consume 了(如果必要则会被 acknowledge)
broker 会丢失持久化消息,如果 broker 在将上述消息写入磁盘前异常。在一定条件下,这种情况会导致 broker 以一种奇怪的方式运行。例如,考虑下述情景:
1. 一个 client 将持久消息 publish 到持久 queue 中
2. 另一个 client 从 queue 中 consume 消息(注意:该消息具有持久属性,并且 queue 是持久化的),当尚未对其进行 ack
3. broker 异常重启
4. client 重连并开始 consume 消息
在上述情景下,client 有理由认为消息需要被(broker)重新 deliver 。但这并非事实:重启(有可能)会令 broker 丢失消息。为了确保持久性,client 应该使用 confirm 机制。如果 publisher 使用的 channel 被设置为 confirm 模式,publisher 将不会收到已丢失消息的 ack(这是因为 consumer 没有对消息进行 ack ,同时该消息也未被写入磁盘)。
3. 编程实现
首先要区别AMQP协议mandatory和immediate标志位的作用。
mandatory和immediate是AMQP协议中basic.pulish方法中的两个标志位,它们都有当消息传递过程中不可达目的地时将消息返回给生产者的功能。具体区别在于:
1. mandatory标志位
当mandatory标志位设置为true时,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返还给生产者;当mandatory设为false时,出现上述情形broker会直接将消息扔掉。
2. immediate标志位
当immediate标志位设置为true时,如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。
RabbitMQ - Publisher的消息确认机制的更多相关文章
- springboot + rabbitmq 用了消息确认机制,感觉掉坑里了
本文收录在个人博客:www.chengxy-nds.top,技术资源共享,一起进步 最近部门号召大伙多组织一些技术分享会,说是要活跃公司的技术氛围,但早就看穿一切的我知道,这 T M 就是为了刷KPI ...
- (转)RabbitMQ消息队列(九):Publisher的消息确认机制
在前面的文章中提到了queue和consumer之间的消息确认机制:通过设置ack.那么Publisher能不到知道他post的Message有没有到达queue,甚至更近一步,是否被某个Consum ...
- RabbitMQ消息队列(九):Publisher的消息确认机制
在前面的文章中提到了queue和consumer之间的消息确认机制:通过设置ack.那么Publisher能不到知道他post的Message有没有到达queue,甚至更近一步,是否被某个Consum ...
- RabbitMQ (十二) 消息确认机制 - 发布者确认
消费者确认解决的问题是确认消息是否被消费者"成功消费". 它有个前提条件,那就是生产者发布的消息已经"成功"发送出去了. 因此还需要一个机制来告诉生产者,你发送 ...
- RabbitMQ 消费者的消息确认机制
消息确认的几点说明: 1. Basic.Ack 发回给 RabbitMQ 以告知,可以将相应 message 从 RabbitMQ 的消息缓存中移除.2. Basic.Ack 未被 consumer ...
- SpringBoot集成RabbitMQ并实现消息确认机制
原文:https://blog.csdn.net/ctwy291314/article/details/80534604 RabbitMQ安装请参照RabbitMQ应用 不啰嗦直接上代码 目录结构如下 ...
- 消息队列RabbitMQ(三):消息确认机制
引言 RabbitMQ的模型是生产者发送信息到 Broker (代理),消费者从 Broker 中取出信息.但是生产者怎么知道消息是否真的发送到 Broker 中了呢?Broker 又怎么知道消息到底 ...
- RabbitMQ 消息确认机制
消息确认机制 在之前异常处理部分就已经写了,对于consumer的异常退出导致消息丢失,可以时候consumer的消息确认机制.重复的就不说了,这里说一些不一样的. consumer的消息确认机制 当 ...
- RabbitMQ学习笔记之五种模式及消息确认机制
本文详细介绍简单模式Simple.工作模式Work.发布订阅模式Publish/Subscribe.Topic.Routing. Maven依赖引用 <dependencies> < ...
随机推荐
- Application特征
1.位置:服务器内存,执行速度快2.使用范围:整个应用程序3.类型:任意类型4.声明周期:应用程序开始创建到销毁
- 1072. Gas Station (30)【最短路dijkstra】——PAT (Advanced Level) Practise
题目信息 1072. Gas Station (30) 时间限制200 ms 内存限制65536 kB 代码长度限制16000 B A gas station has to be built at s ...
- openstack-glance-api.service start request repeated too quickly, refusing to start
问题描写叙述 openstack J版 centos7部署 重新启动服务时起不来,日志也不报错.以glance服务为例,例如以下: # systemctl start openstack-glance ...
- 『GCD』详解
2. GCD 任务和队列 学习 GCD 之前,先来了解 GCD 中两个核心概念:任务和队列. 任务:就是执行操作的意思,换句话说就是你在线程中执行的那段代码.在 GCD 中是放在 block 中的.执 ...
- Html.RenderPartial使用三个参数
Html.RenderPartial("usercontrolurl", model, ViewDataDictionary) 当使用三个参数时可以这样使用: var data = ...
- ffmpeg resize and scale
ffmpeg缩小视频尺寸 | 楚盟博客 https://www.5yun.org/13126.html ffmpeg -i test.mp4 -s 480×360 out.mp4 常用分辨率: 108 ...
- ROUND function and arithmetic overflow
遇到如下错误 Arithmetic overflow error converting expression to data type numeric. ), ); https://stackover ...
- Python Matplotlib模块--pylab
#-*- coding: utf-8 -*- ''' subplot(m,n,p):其中,m表示是图排成m行,n表示图排成n列,也就是整个figure中有n个图是排成一行的,一共m行,如果m=2就是表 ...
- JForum论坛添加UEditor文本编辑器
在使用JForum论坛中发现论坛自带的文本编辑器不好用,不能上传图片,样式编辑也很麻烦,就想着把这个文本编辑器替换掉,我这里选用的是百度的开源富文本编辑器UEditor 替换后的效果图 替换方法如下 ...
- CodeForces 632C Grandma Laura and Apples (模拟)
题意:有n个人买苹果,当苹果剩余偶数时买走一半,当苹果剩余奇数时,先买走一半,再用半价买走一个苹果,最终苹果恰好卖完.农民收入为多少. 析:反向模拟. 代码如下: #pragma comment(li ...