一、应用背景

  今天做一个需求,要将RabbitMQ中的任务取出并执行,为防止任务执行期间出错,设置NO_ACK=FALSE标志,这样、一旦任务没有应答的话,相应的任务就会被RabbitMQ自动Re-Queue,避免丢失任务。然而、由于任务执行时间较长,通常需要五、六分钟,甚至更长;我们都知道一旦一个任务被取出执行,该任务就从Ready状态更改成Unacked状态。如图所示:

  当这个任务执行完之后,程序将向RabbitMQ发送ACK消息确认,RabbitMQ在收到ACK消息后,会将该任务移出队列;然而、问题出在任务尚未执行完毕【执行时间太久】,RabbitMQ再等了一段时间【大约两三分钟】后,一直没有收到ACK确认消息,就将该任务自动Re-Queue了【我是一个生产者,一个消费者模式】,也就是说、我们这里发生了死循环【任务永远也执行不完,因为会一直Re-Queue】。

二、延长RabbitMQ ACK应答时间

  到这里,我们急需解决的问题就是,怎么能设置RabbitMQ延长等待ACK的时间,百度一下、两下,各种读网络文档,研究操作RabbitMQ工作的文档,查了一圈资料也没查出怎么延长RabbitMQ ACK时间【废柴啊】。至此、一直查不出来,就想问一下网友的你,你知道怎么延长RabbitMQ接受ACK应答时间么?

三、改变解决问题方式

  在查不出如何延长ACK应答时间后,我将注意力转向如何检测当前任务操作超时的,后来在官网看到这么一段话:

  链接官网位置:http://www.rabbitmq.com/heartbeats.html#heartbeats-timeout

  

   后面、就简单测试下将heartbeat参数设置为0,以禁用心跳检测,这样基本解决了我的问题;虽然官方不建议这么做,但也是一种解决思路,如果大家有什么更好的解决办法,烦请在下面留言【先谢谢啦】。

  至此、这个问题基本阐述清楚了,如果有遇到的小伙伴,也请参考下上面的操作。

  测试代码:

# import json
# from concurrent.futures import ThreadPoolExecutor
from queue import Queue
# from threading import Thread from pika import BasicProperties, BlockingConnection, URLParameters
from pika.exceptions import ConnectionClosed # from automation.aiclient.aiclient import AsyncAIRequestManager class RabbitMQManager:
def __init__(self, host = 'localhost', qname = 'queue'):
self.params = URLParameters(host)
self.qname = qname
self.prod_conn = None
self.prod_chan = None
self.cons_conn = None
self.cons_chan = None
self.ai_signton = None def init_prod_conn(self):
# create send connection
self.prod_conn = BlockingConnection(self.params)
self.prod_chan = self.prod_conn.channel()
self.prod_chan.queue_declare(queue = self.qname, durable = True) def init_cons_conn(self):
# create receive connection
self.cons_conn = BlockingConnection(self.params)
self.cons_chan = self.cons_conn.channel()
self.cons_chan.basic_qos(prefetch_count = 1)
self.cons_chan.basic_consume(self.callback, queue = self.qname) def produceMessages(self, msg = None):
try:
if isinstance(msg, str):
self.prod_chan.basic_publish(exchange = '',
routing_key = self.qname,
body = msg,
properties = BasicProperties(
delivery_mode = 2, # make message persistent
))
elif isinstance(msg, Queue):
while 0 != msg.qsize():
item = msg.get()
self.prod_chan.basic_publish(exchange = '',
routing_key = self.qname,
body = item,
properties = BasicProperties(
delivery_mode = 2, # make message persistent
))
else:
pass except Exception as e:
if isinstance(e, ConnectionClosed):
print('Reconnection established!')
self.init_prod_conn()
# last connection close, re-produce msg
self.produceMessages(msg)
else:
print('Produce msg exception Occur, please check following error message:')
print(e) def consumeMessages(self):
try:
self.cons_chan.start_consuming()
except Exception as e:
print('Consume msg exception Occur, please check following error message:')
print(e)
if isinstance(e, ConnectionClosed):
print('Reconnection established!')
self.init_cons_conn()
self.consumeMessages() def callback(self, ch, method, properties, body):
# handle message body
print('callback....')
print(body)
try:
print('Consuming....')
self.cons_conn.process_data_events()
# 模拟处理任务时间
import time
time.sleep(300)
# if None == self.ai_signton:
# self.ai_signton = AsyncAIRequestManager()
# self.ai_signton.run(eval(json.loads(json.dumps(body.decode('utf-8')), encoding = 'utf-8')))
ch.basic_ack(delivery_tag = method.delivery_tag)
# t = Thread(target = self.ai_signton.syncToDatabase())
# t.start() except Exception as e:
if isinstance(e, ConnectionClosed):
raise ConnectionClosed('Connection has been closed, send to reconnection.')
else:
print('Current error msg:')
print(e) def close_prod_conn(self):
if None != self.prod_conn:
self.prod_conn.close() def close_cons_conn(self):
if None != self.cons_conn:
self.cons_conn.close() def close(self):
self.close_prod_conn()
self.close_cons_conn()

  

RabbitMQ死循环-延长ACK时间的更多相关文章

  1. rabbitmq 不发送ack消息如何处理:rabbitmq可靠发送的自动重试机制

    转载地址:http://www.jianshu.com/p/6579e48d18ae http://www.jianshu.com/p/4112d78a8753 接这篇 在上文中,主要实现了可靠模式的 ...

  2. RabbitMq + Spring 实现ACK机制

    概念性解读(Ack的灵活) 首先啊,有的人不是太理解这个Ack是什么,讲的接地气一点,其实就是一个通知,怎么说呢,当我监听消费者,正常情况下,不会出异常,但是如果是出现了异常,甚至是没有获取的异常,那 ...

  3. RabbitMQ消费端ACK与重回队列机制,TTL,死信队列详解(十一)

    消费端的手工ACK和NACK 消费端进行消费的时候,如果由于业务异常我们可以进行日志的记录,然后进行补偿. 如果由于服务器宕机等严重问题,那么我们就需要手工进行ACK保障消费端成功. 消费端重回队列 ...

  4. spring boot 延长 Session 时间

    1.查看session时间    默认1800s 通过request.getSession().getMaxInactiveInterval()可以查看你的session时间 2.延长session ...

  5. rabbitmq 不发送ack消息如何处理: RabbitMQ 消息确认以及消息消费方处理消息时候抛出了异常以

    本篇的代码使用的前面两篇文章<RabbitMQ与Spring整合之消息生产方>和<RabbitMQ与Spring整合之消息消费方>的代码,这两篇文件里配置文件的名称不正确,不可 ...

  6. Windows Server 2016 开启远程连接并延长过期时间

    按照下面文章配置,做完1.2步即可,其中协议号码填写 4954438 亲测有效! Server 2016默认远程桌面连接数是2个用户,如果多余两个用户进行远程桌面连接时,系统就会提示超过连接数,可以通 ...

  7. .net Session延长过期时间

    一.全局网站(即服务器)级 IIS-网站-属性-Asp.net-编辑配置-状态管理-会话超时(分钟)-设置为120,即为2小时,即120分钟后如果当前用户没有操作,那么Session就会自动过期. 二 ...

  8. 延长Toast显示时间

    ---恢复内容开始--- 由于Toast的显示时间只有两种: Toast.LENGTH_SHORT: 2秒 Toast.LENGTH_LONG: 3.5秒 而且是写死的,没给开发者自定义时间的权利,所 ...

  9. 面试官:RabbitMQ过期时间设置、死信队列、延时队列怎么设计?

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 RabbitMQ我们经常的使用, ...

随机推荐

  1. Hadoop Mapreduce 中的FileInputFormat类的文件切分算法和host选择算法

    文件切分算法 文件切分算法主要用于确定InputSplit的个数以及每个InputSplit对应的数据段. FileInputFormat以文件为单位切分成InputSplit.对于每个文件,由以下三 ...

  2. Struts2的介绍

    Struts2的介绍 制作人:全心全意 Struts引用的是MVC(Model-View-Controller,模型-视图-控制器)设计理念.目前,JavaWeb应用MVC设计理念的框架有很多,如St ...

  3. 腾讯云,搭建Git服务器

    下载安装 git 任务时间:5min ~ 10min Git 是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. 此实验以 CentOS 7.2 x64 的系统为环境,搭建 ...

  4. LA 3029 Subsequence

    LA 3029 A sequence of N positive integers (10 < N < 100 000), each of them less than or equal ...

  5. 【02】json语法

    [02] JSON 语法是 JavaScript 语法的子集. JSON 语法规则 JSON 语法是 JavaScript 对象表示法语法的子集. 数据在名称/值对中 数据由逗号分隔 花括号保存对象 ...

  6. 数据库删除数据表重复数据,只留下ID较小的行

    删除表中重复数据,留下ID比较小的行 delete from 表 where [重复字段] in (select [重复字段] from 表 group by 字段 having count([字段] ...

  7. Switch Game

    Problem Description There are many lamps in a line. All of them are off at first. A series of operat ...

  8. MYSQL中的数值型数据类型与字符串类型

    /* 数值型数据类型主要用来存储数字,包含的类型有: TINYINT.SMALLINT.MEDIUMINT. INT(INTEGER). BIGINT TINGINT占1个字节,SMALLINT占2个 ...

  9. 演练:使用VS2010 C# 创作简单的多线程组件

    BackgroundWorker 组件取代了 System.Threading 命名空间并添加了功能:但是,可以选择保留 System.Threading 命名空间以实现向后兼容并供将来使用.有关更多 ...

  10. 【python】字符遍历

    Python为我们提供了很多便捷的方式去遍历一个字符串中的字符.比如,将一个字符串转换为一个字符数组(列表): theList = list(theString) 同时,我们可以方便的通过for语句进 ...