我有这个队列系统,我使用pika的BlockingConnection来使用https://www.cloudamqp.com/上托管的rabbitmq队列。 以下是连接的设置方式:
params = pika.URLParameters(self.queue_url)
self.connection = pika.BlockingConnection(params)
self.channel = self.connection.channel()
self.channel.queue_declare(queue=self.queue_name, durable=True)
self.channel.basic_qos(prefetch_count=1)
# set up subscription on the queue
self.channel.basic_consume(self._on_new_task,
queue=self.queue_name,
no_ack=False)
self.channel.start_consuming()
def _on_new_task(self, ch, method, properties, body):
logging.info("Processing new scan")
"""
Do long running task here
"""
self.channel.basic_ack(delivery_tag=method.delivery_tag)
# Program crashes here
从队列中处理任务最多可能需要15分钟。但是,大多数情况下,处理任务只需要2-3分钟,然后一切正常。当它需要> 5分钟我从pika得到以下错误:
ERROR - pika.adapters.base_connection - Read empty data, calling disconnect
WARNING - pika.adapters.base_connection - Socket closed when connection was open
WARNING - pika.connection - Disconnected from RabbitMQ at squirrel.rmq.cloudamqp.com:5672 (0): Not specified
CRITICAL - pika.adapters.blocking_connection - Connection close detected
显然,basic_ack没有成功处理,因为任务仍然在任务队列中,导致无限循环,任务从未从队列中释放。
我已经尝试调整心跳,两者都是0,30,600等,但看起来心跳不能用于阻塞连接,因为长时间运行的任务阻止连接发送心跳(?)
程序在docker容器内运行。在AWS ECS2上托管容器时遇到问题,但在家用PC上运行容器时却没有。因此在我看来,ECS2正在取消空闲连接(?)。 这个假设得到了运行时的支持
for i in range(1,10):
self.connection.sleep(60)
self.connection.process_data_events()
而不是长时间运行的任务,一切都很好,可能是因为心跳被发送并保持连接活着。
不确定如何解决这个问题。用SelectConnection替换pika的BlockingConnection有什么意义吗?或EC2 / ECS2中是否有任何配置不会拆除空闲连接?