rabbitmq 重复ACK导致消息丢失
rabbitmq 重复确认导致消息丢失
背景
rabbitmq 在应用场景中,大多采用工作队列 work-queue的模式。
在一个常见的工作队列模式中,消费者 worker 将不断的轮询从队列中拉取最新消息,当队列负载压力增大时允许添加多个worker 进行处理。
然而执行一个任务可能需要相当的时长,这是由业务特性所决定的;如果 worker执行任务过程中出现异常甚至宕机,此时消息便会丢失,这是简单消息队列难以解决的问题。
rabbitmq 采用了消息确认机制来防止此类问题,在该机制中,worker需要向 MQ Server 返回 ACK响应以表示消息已确认处理;
在以下情况下,rabbitmq 会对消息进行重新投递:
1 client 未响应ACK, 主动关闭 Channel;
2 client 未响应ACk, 网络异常断开;
消息的重发机制没有超时限制,只要client 不响应ACK,那么会一直投递;
如果启用了消息持久化机制,那么消息将有进一步的保障。
问题描述及分析
1 客户端为简化应答处理,可以设置自动应答选项,如:
boolean autoAck = false;
channel.basicConsume(TASK_QUEUE_NAME, autoAck, consumer);
2 如果不启用自动应答,需要应用代码手动进行应答:
try {
doWork(message);
} finally {
logger.info(" xxx work done");
channel.basicAck(envelope.getDeliveryTag(), false);
}
3 当两种方案同时存在
由于客户端的编码失误,先启用了自动应答选项,又在应用代码执行了应答的代码:
// enable autoAck
boolean autoAck = true;
consumerChannel.basicConsume(queueName, autoAck, this);
//...
// snipper from Consumer.handleDelivery method
// send ack to server
try {
consumerChannel.basicAck(deliveryTag, true);
} catch (Exception e) {
}
多了一次确认,应用代码貌似一切如常。 但在频繁进行消息收发测试时发现 消息存在随机性丢失处理的情况!
检查 rabbitmq server日志发现以下异常:
{amqp_error,precondition_failed,"unknown delivery tag 1",'basic.ack'}
...
{amqp_error,precondition_failed,"unknown delivery tag 1",'basic.ack'}
...
{amqp_error,precondition_failed,"unknown delivery tag 1",'basic.ack'}
...
提示未知的 delivery tag=1,该字段为MQ server 用于消息确认的标记,服务端因无法识别而打印错误。
另外一个现象则是,连续收发消息 5次,其中丢失消息处理1次,而 rabbitmq server错误日志出现 4次!
经过分析,发现问题原因所在:
rabbitmq 为每一个channel维护了一个delivery tag的计数器,这里采用正向自增,新消息投递时自增,当消息响应时自减;
在连续收发的场景中,由于消息发送的间隔较短,部分消息因 consumer的重复确认被rabbitmq 当做已处理而丢弃。
解决方案
取消consumer 的自动应答机制,仅保留手动应答的处理,问题解决。
参考资料
关于 rabbitmq 消息确认机制:
http://www.rabbitmq.com/confirms.html#when
rabbitmq 重复ACK导致消息丢失的更多相关文章
- APNS导致消息丢失和发送效率原因
http://blog.csdn.net/tlq1988/article/details/9612237 首先说明一下,本文只是介绍一些容易被开发者忽视,而导致性能低下问题.并不是介绍如何向苹果设备成 ...
- 解决RabbitMQ消息丢失问题和保证消息可靠性(一)
原文链接(作者一个人):https://juejin.im/post/5d468591f265da03b810427e 工作中经常用到消息中间件来解决系统间的解耦问题或者高并发消峰问题,但是消息的可靠 ...
- RabbitMQ防止消息丢失
转载请注明出处 0.目录 RabbitMQ-从基础到实战(1)— Hello RabbitMQ RabbitMQ-从基础到实战(3)— 消息的交换 1.简介 RabbitMQ中,消息丢失可以简单的分为 ...
- 如何处理RabbitMQ 消息堆积和消息丢失问题
消息堆积 解决方案: 增加消费者或后台相关组件的吞吐能力 增加消费的多线程处理 根据不同的业务实现不同的丢弃任务,选择不同的策略淘汰任务 默认情况下,RabbitMQ消费者为单线程串行消费,设置并行消 ...
- RabbitMQ 和 Kafka 的消息可靠性对比
RabbitMQ和Kafka都提供持久的消息保证.两者都提供至少一次和至多一次的保证,另外,Kafka在某些限定情况下可以提供精确的一次(exactly-once)保证. 让我们首先理解一下上述术语的 ...
- RabbitMQ-从基础到实战(2)— 防止消息丢失
转载请注明出处 1.简介 RabbitMQ中,消息丢失可以简单的分为两种:客户端丢失和服务端丢失.针对这两种消息丢失,RabbitMQ都给出了相应的解决方案. 2.防止客户端丢失消息 如图,生产者P向 ...
- RabbitMQ实战:理解消息通信
RabbitMQ是一个开源的消息代理和队列服务器,可以通过基本协议在完全不同的应用之间共享数据,可以将作业排队以便让分布式服务进行处理. 本篇介绍下消息通信,首先介绍基础概念,将这些概念映射到AMQP ...
- 【RabbitMQ】如何进行消息可靠投递【上篇】
说明 前几天,突然发生线上报警,钉钉连发了好几条消息,一看是RabbitMQ相关的消息,心头一紧,难道翻车了? [橙色报警] 应用[xxx]在[08-15 16:36:04]发生[错误日志异常],al ...
- RocketMQ消息丢失解决方案:同步刷盘+手动提交
前言 之前我们一起了解了使用RocketMQ事务消息解决生产者发送消息时消息丢失的问题,但使用了事务消息后消息就一定不会丢失了吗,肯定是不能保证的. 因为虽然我们解决了生产者发送消息时候的消息丢失问题 ...
随机推荐
- eclipse或myeclipse快捷键
MyEclipse 快捷键1(CTRL) ------------------------------------- Ctrl+1 快速修复 Ctrl+D: 删除当前行 Ctrl+Q 定位到最后编辑 ...
- [解决方案] pythonchallenge level 6
查看页面代码,知道找zip www.pythonchallenge.com/pc/def/channel.zip,查看zip下的readme.txt知道从90052,跑一遍知道要收集zip的comme ...
- 第二章 XHTML 基础
元素与标签术语,HTML/XHTMLXHTML之间的联系区别在XHTML中,所有元素之间必须完成正确的嵌套,元素必须是闭合的,必须小写.必须有个跟元素HTML. 标题标<h1>语法:< ...
- C# 生成条形码图片,效果不错
//首先引用 条码库BarcodeLib.dll using System; using System.Collections.Generic; using System.Linq; using Sy ...
- Map循环的三种方法
import java.util.HashMap; import java.util.Iterator; import java.util.Map; public class MapTest { pu ...
- LaTex表格内单元格内容强制换行
/newcommand{/tabincell}[2]{/begin{tabular}{@{}#1@{}}#2/end{tabular}}%放在导言区 %然后使用&/tabincell{c}{} ...
- Aspose.Cells 首次使用,用到模版填充数据,合并单元格,换行
Aspose.Cells 首次使用,用到模版填充数据,合并单元格,换行 模版格式,图格式是最简单的格式,但实际效果不是这种,实际效果图如图2 图2 ,注意看红色部分,一对一是正常的,但是有一对多的订单 ...
- 关于JavaScript 中的变量
JS的变量声明语句永远是在其作用域中最先执行的,不论其定义的位置在哪里: 函数体内部,局部变量的优先级比同名的全局变量高. Javas作用域分类 未使用var定义的变量不论定义在什么位置都是全局变量, ...
- 转载:Android横屏竖屏切换的问题
一.禁止横竖屏转换 Android横竖屏切换在手机开发中比较常见,很多软件在开发过程中为了避免横竖屏切换时引发不必要的麻烦,通常禁止掉横竖屏的切换, 通过在AndroidManifest.xml中设置 ...
- 修改hive分区表,在分区列前增加一个字段
本文主要为了测试,在有数据的分区表中增加新的一个非分区字段后,新数据加入表中是否正常. 原始数据 1;zhangsan 2;zhangsan 3;zhangsan 4;lisi 5;lisi 6;li ...