一、应用背景

  今天做一个需求,要将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. 腾讯云,体验域名注册解析与SSL证书

    体验域名注册解析与SSL证书 购买域名 任务时间:30min ~ 60min 在腾讯云上购买域名 首先需要在腾讯云上购买域名, 点击以下链接可以观看购买操作的指引 如何在腾讯云上购买域名 域名解析 域 ...

  2. [bzoj4521][Cqoi2016][手机号码] (数位dp+记忆化搜索)

    Description 人们选择手机号码时都希望号码好记.吉利.比如号码中含有几位相邻的相同数字.不含谐音不 吉利的数字等.手机运营商在发行新号码时也会考虑这些因素,从号段中选取含有某些特征的号 码单 ...

  3. i2c中start和restart的区别

    有的硬件芯片提供了一个个寄存器,供我们很好的操作i2c,但是,在用的时候,我们是不知道他到地是怎么操作的,下边,我就探讨下i2c中的start和restart的区别. start是在scl是高电平的时 ...

  4. java 访问对象私有变量

    Captcha captcha = getCaptcha(captchaId); // 通过反射获取验证码值 Class<?> classType = captcha.getClass() ...

  5. 【04】JSONP 教程

    JSONP 教程 Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据. 为什么我们从不同的域 ...

  6. kafka+spark-streaming实时推荐系统性能优化笔记

    1) --conf spark.dynamicAllocation.enabled=false 如果正在使用的是CDH的Spark,修改这个配置为false:开源的Spark版本则默认是false. ...

  7. Linux下汇编语言学习笔记35 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  8. Holedox Eating HDU4302 模拟

    Problem Description Holedox is a small animal which can be considered as one point. It lives in a st ...

  9. Oracle中的 row_number() over (partition by order by ) 用法

    oracle 里面经常这样用 select col1,col2..., row_number() over (partition by colx order by coly) from table_n ...

  10. Docker创建PHP镜像

    Step: 1. 创建Dockerfile FROM php:7.0-apache RUN chmod -R 755 /var/www 2. 创建镜像 docker build -t docker_n ...