一、应用背景

  今天做一个需求,要将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. webpack3 + vue 添加 serviceWorker

    新的vue脚手架已经可以自带pwa了,本文主要针对旧版的webpack. 先装三个插件: $npm i register-service-worker sw-precache-webpack-plug ...

  2. web视频播放插件:Video For Everybody

    相比其它的web视频播放插件(video.js , jwplayer等)来说,Video For Everybody(极力推荐)是一款更好的视频播放插件,无需任何下载,支持html5以及flash播放 ...

  3. 抓包工具的感触(charles and fiddler)

    最近测mobile,一直徘徊在fiddler 和 charles之间: charles 的证书装了 ,才能正常抓包: 后来因为重定向,分享到扣扣,微信的跳转功能,跳转到wap 或者跳转到PC  或者跳 ...

  4. Python基础之函数参数与返回值进阶

    参数作用:如果外界希望在函数内部处理数据,就可以将数据作为参数传入函数内部: 返回值作用:如果希望一个函数函数执行完成后,向外界报告函数的执行结果,就可以使用函数的返回值. 函数的返回值 进阶 利用元 ...

  5. 码云私人代码 SSH 设置----https://blog.csdn.net/kkaazz/article/details/78667573

    码云私人代码 SSH 设置 https://blog.csdn.net/kkaazz/article/details/78667573

  6. Ural 1091 Tmutarakan Exams

    Tmutarakan Exams Time Limit: 1000ms Memory Limit: 16384KB This problem will be judged on Ural. Origi ...

  7. Spring技术内幕:Spring AOP的实现原理(五)

    7.Advice通知的实现 AopProxy代理对象生成时,其拦截器也一并生成.以下我们来分析下Aop是怎样对目标对象进行增强的.在为AopProxy配置拦截器的实现中,有一个取得拦截器配置过程,这个 ...

  8. Solidworks如何导入和使用模板文件

    将模板文件拷贝到Solidworks目录(可以是任意目录)     点击工具-选项-文件位置,然后把文件夹添加进去   新建文件的时候选择高级模式,然后就会看到已经出现了我们导入的模板文件       ...

  9. 自己定义控件:onDraw 方法实现仿 iOS 的开关效果

    概述 本文主要解说怎样在 Android 下实现高仿 iOS 的开关按钮,并不是是在 Android 自带的 ToggleButton 上改动,而是使用 API 提供的 onDraw.onMeasur ...

  10. 将一个对象相同的属性(不区分大小写)赋值给一个新对象 DataTable的一个简单的扩展

    将一个对象相同的属性(不区分大小写)赋值给一个新对象   1 public static T Mapper<S, T>(S source) 2 { 3 T t = Activator.Cr ...