4、RabbitMQ-消息应答与消息持久化

消息应答( Message acknowledgment)

1、 Message acknowledgment(消息应答)

执行任务可能需要几秒钟。你可能想知道如果其中一个消费者开始一项长期任务并且只是部分完

成而死亡会发生什么。使用我们当前的代码,一旦RabbitMQ向消费者发送消息,它立即将其标

记为删除。在这种情况下,如果你杀死一个工人,我们将丢失它刚刚处理的消息。我们还将丢

失分发给这个特定工作者但尚未处理的所有消息。

但我们不想失去任何任务。如果工人死亡,我们希望将任务交付给另一名工人。

为了确保消息永不丢失,RabbitMQ支持 消息确认。消费者发回ack(nowledgement)告诉RabbitMQ已收到,

处理了特定消息,RabbitMQ可以自由删除它。

如果消费者死亡(其通道关闭,连接关闭或TCP连接丢失)而不发送确认,RabbitMQ将理解消息未完全处理并将重新

排队。如果同时有其他在线消费者,则会迅速将其重新发送给其他消费者。这样你就可以确保没有消息丢失,即使工人偶尔会死亡。

没有任何消息超时; 当消费者死亡时,RabbitMQ将重新发送消息。即使处理消息需要非常长的时间,也没关系。

默认情况下,手动消息确认已打开。在前面的示例中,我们通过autoAck = true 标志明确地将它们关闭。

一旦我们完成任务,就应该将此标志设置为false并从工作人员发送适当的确认。

消息持久化(Message durability)

http://www.rabbitmq.com/tutorials/tutorial-two-java.html

我们已经学会了如何确保即使消费者死亡,任务也不会丢失。

但是如果RabbitMQ服务器停止,我们的任务仍然会丢失。

当RabbitMQ退出或崩溃时,它将忘记队列和消息,除非你告诉它不要。

确保消息不会丢失需要做两件事:我们需要将队列和消息都标记为持久。

DeclareOk com.rabbitmq.client.Channel.queueDeclare(String queue, boolean durable,
boolean exclusive, boolean autoDelete, Map<String, Object> arguments) throws IOException

已经运行的工程之后,再次运行将会报错!!!!

尽管这行代码是正确的,他不会运行成功。因为我们已经定义了一个名叫 test_queue_work 的未持久化的队列。

RabbitMQ 不允许使用不同的参数设定重新定义已经存在的队列,并且会返回一个错误。

一个快速的解决方案——就是声明一个不同名字的队列,比如 task_queue。或者我们登录控制台将队列删除就可以了

官方解释:

将消息标记为持久性并不能完全保证消息不会丢失。虽然它告诉RabbitMQ将消息保存到磁盘,

但是当RabbitMQ接受消息并且尚未保存消息时,仍然有一个短时间窗口。

此外,RabbitMQ不会为每条消息执行fsync(2) - 它可能只是保存到缓存而不是真正写入磁盘。

持久性保证不强,但对于我们简单的任务队列来说已经足够了。

原文地址:https://www.cnblogs.com/Mrchengs/p/10530907.html

时间: 2024-11-14 12:07:23

4、RabbitMQ-消息应答与消息持久化的相关文章

rabbitmq 重复ACK导致消息丢失

rabbitmq 重复确认导致消息丢失 背景 rabbitmq 在应用场景中,大多采用工作队列 work-queue的模式. 在一个常见的工作队列模式中,消费者 worker 将不断的轮询从队列中拉取最新消息,当队列负载压力增大时允许添加多个worker 进行处理.然而执行一个任务可能需要相当的时长,这是由业务特性所决定的:如果 worker执行任务过程中出现异常甚至宕机,此时消息便会丢失,这是简单消息队列难以解决的问题. rabbitmq 采用了消息确认机制来防止此类问题,在该机制中,work

RabbitMQ介绍2 - 理解消息AMQP

理解消息AMQP通信.官方解释: http://www.rabbitmq.com/tutorials/amqp-concepts.html 概念:生产者producer,消费者consumer,队列queue,交换器exchange,路由键routing key,绑定键binding key. producer发布消息,消息经过交换器传播放入队列,消费者从队列中得到消息. ConnectionFactory, connection, channel信道.connectionFactory用来建立

Rabbit mq订阅方式获取消息并可设置持久化

Rabbit 通过方式获取消息:订阅方式其实是向queue注册consumer,通过rpc向queue server发送注册consumer的消息,rabbitMQ Server在收到消息后,根据消息的内容类型判断这是一个订阅消息,这样当MQ 中queue有消息时,会自动把消息通过该socket(长连接)通道发送出去. 可以通过 channel.basicQos(1); 设置RabbitMQ调度分发消息的方式,也就是告诉RabbitMQ每次只给消费者处理一条消息,也就是等待消费者处理完并且已经对

RabbitMQ实战:理解消息通信

本系列是「RabbitMQ实战:高效部署分布式消息队列」书籍的总结笔记. 前段时间总结完了「深入浅出MyBatis」系列,对MyBatis有了更全面和深入的了解,在掘金社区也收到了一些博友的喜欢,很高兴.另外,短暂的陪产假就要结束了,小宝也二周了,下周二就要投入工作了,希望自己尽快调整过来,加油努力. 从本篇开始总结「RabbitMQ实战」系列的阅读笔记,RabbitMQ是一个开源的消息代理和队列服务器,可以通过基本协议在完全不同的应用之间共享数据,可以将作业排队以便让分布式服务进行处理. 本篇

RabbitMQ,为应对消息从发送到消费,各个环节消息丢失的解决方案

1.发送方   为保证消息到达exchange,在这个过程中不丢失.  用事务或者发送方确认机制  见<RabbitMQ实战指南>4.8节 2.为保证消息不会因为到达exchange后,无法路由到任何一个队列而丢失 解决方案一:发送方发送消息时 令mandatory参数=true,用ReturnListener异步接收没有任何队列接收而返回给发送方的消息.  见<RabbitMQ实战指南>4.1.1节 解决方案二:给exchange指定一个备份交换器及对应队列,到达交换器的消息如何

rabbitmq和redis用作消息队列的区别

将redis发布订阅模式用做消息队列和rabbitmq的区别: 可靠性   redis :没有相应的机制保证消息的可靠消费,如果发布者发布一条消息,而没有对应的订阅者的话,这条消息将丢失,不会存在内存中:rabbitmq:具有消息消费确认机制,如果发布一条消息,还没有消费者消费该队列,那么这条消息将一直存放在队列中,直到有消费者消费了该条消息,以此可以保证消息的可靠消费: 实时性 redis:实时性高,redis作为高效的缓存服务器,所有数据都存在在服务器中,所以它具有更高的实时性 消费者负载均

RabbitMQ 和 Kafka 的消息可靠性对比

RabbitMQ和Kafka都提供持久的消息保证.两者都提供至少一次和至多一次的保证,另外,Kafka在某些限定情况下可以提供精确的一次(exactly-once)保证. 让我们首先理解一下上述术语的含义: 至多一次投递:消息绝对不会被重复投递,但是消息可能丢失 至少一次投递:消息绝对不会被丢失,但是有可能重复被消费 精确的一次投递:消息系统的圣杯.所有的消息精确的被投递一次. “投递”貌似不是准确的语言描述,“处理”才是.无论怎么描述,我们关心的是,消费者能否处理消息,以及处理的次数.但是使用

【RabbitMQ】如何进行消息可靠投递【上篇】

说明 前几天,突然发生线上报警,钉钉连发了好几条消息,一看是RabbitMQ相关的消息,心头一紧,难道翻车了? [橙色报警]?应用[xxx]在[08-15?16:36:04]发生[错误日志异常],alertId=[xxx].由[org.springframework.amqp.rabbit.listener.BlockingQueueConsumer:start:620]触发. 应用xxx?可能原因如下 服务名为: ?异常为:org.springframework.amqp.rabbit.lis

Python实现RabbitMQ中6种消息模型

RabbitMQ与Redis对比 ? RabbitMQ是一种比较流行的消息中间件,之前我一直使用redis作为消息中间件,但是生产环境比较推荐RabbitMQ来替代Redis,所以我去查询了一些RabbitMQ的资料.相比于Redis,RabbitMQ优点很多,比如: 具有消息消费确认机制 队列,消息,都可以选择是否持久化,粒度更小.更灵活. 可以实现负载均衡 RabbitMQ应用场景 异步处理:比如用户注册时的确认邮件.短信等交由rabbitMQ进行异步处理 应用解耦:比如收发消息双方可以使用