【问题标题】:Getting "pika.exceptions.ConnectionClosed" error while using rabbitmq in python在 python 中使用 rabbitmq 时出现“pika.exceptions.ConnectionClosed”错误
【发布时间】:2014-02-27 06:49:46
【问题描述】:

我在 :http://www.rabbitmq.com/tutorials/tutorial-two-python.html 中使用“hello world”教程。 worker.py 是这样的

import pika
import time


connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='task_queue', durable=True)
print ' [*] Waiting for messages. To exit press CTRL+C'

def callback(ch, method, properties, body):
    print " [x] Received %r" % (body,)
    time.sleep( body.count('.') )
    print " [x] Done"
    ch.basic_ack(delivery_tag = method.delivery_tag)

channel.basic_qos(prefetch_count=1)
channel.basic_consume(callback,
                      queue='task_queue')

channel.start_consuming()

我已经在我的工作中使用了这个代码来实现。一切顺利,直到队列中出现一个点,在打印[x] Done后引发异常@

Traceback (most recent call last):
  File "hullworker2.py", line 242, in <module>
    channel.basic_consume(callback,queue='test_queue2')
  File "/usr/local/lib/python2.7/dist-packages/pika/channel.py", line 211, in basic_consume
    {'consumer_tag': consumer_tag})])
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 904, in _rpc
    self.connection.process_data_events()
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 88, in process_data_events
    if self._handle_read():
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 184, in _handle_read
    super(BlockingConnection, self)._handle_read()
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/base_connection.py", line 300, in _handle_read
    return self._handle_error(error)
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/base_connection.py", line 264, in _handle_error
    self._handle_disconnect()
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 181, in _handle_disconnect
    self._on_connection_closed(None, True)
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 232, in _on_connection_closed
    self._channels[channel]._on_close(method_frame)
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 817, in _on_close
    self._send_method(spec.Channel.CloseOk(), None, False)
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 920, in _send_method
    self.connection.send_method(self.channel_number, method_frame, content)
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 120, in send_method
    self._send_method(channel_number, method_frame, content)
  File "/usr/local/lib/python2.7/dist-packages/pika/connection.py", line 1331, in _send_method
    self._send_frame(frame.Method(channel_number, method_frame))
  File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 245, in _send_frame
    super(BlockingConnection, self)._send_frame(frame_value)
  File "/usr/local/lib/python2.7/dist-packages/pika/connection.py", line 1312, in _send_frame
    raise exceptions.ConnectionClosed
pika.exceptions.ConnectionClosed

我不明白连接是如何在进程之间自动关闭的。对于队列中的 100 条消息,进程运行良好,然后突然出现此错误。 任何帮助表示赞赏。

【问题讨论】:

  • 你能复制/粘贴你得到的堆栈跟踪错误吗?它应该以 Traceback(最近一次调用最后一次)之类的开头:文件“”,第 1 行,在 .....
  • @kobejohn 我已经更新了问题请看
  • 我没有设置 rabbitmq,所以我只是猜测。回溯显示 basic_consume 中的错误似乎很奇怪。在 start_sumption() 之前不应该有任何回调运行,对吗?这在崩溃之前可以工作多长时间?
  • 30-40 分钟,然后它会显示结果并崩溃。再次,如果我启动工作人员,它会收到相同的消息
  • 这个错误不是来自worker.py,是吗?也许您在错误的地方寻找问题的根源?能给个简化版的 hullworker2.py 吗?另外,如果您可以捕获 ConnectionClosed 异常并重新启动工作程序,您会失去工作吗?我想你会没事的,因为你正在使用确认,它在被确认之前不会完成工作。如果没问题,那么您可以在必要时重新启动作为临时修复。

标签: python rabbitmq pika


【解决方案1】:

heartbeats 的概念。这基本上是服务器如何确保客户端仍然连接的一种方式。

当你这样做时

time.sleep( body.count('.') )

您将代码阻止了N 秒数。这意味着如果服务器想发送一个heartbeat 帧来检查您的客户端是否还活着,那么它不会得到响应,因为您的代码被阻塞并且不知道心跳是否到达。

您应该使用connection.sleep(),而不是使用time.sleep(),这也会使代码“休眠”N 秒数,但它也会与服务器通信并做出响应。

 sleep(duration)[source]

    A safer way to sleep than calling time.sleep() directly which will keep the adapter from ignoring frames sent from RabbitMQ. The connection will “sleep” or block the number of seconds specified in duration in small intervals.

【讨论】:

  • 而这个答案解决了问题中的问题。我认为它并没有很好地解决长时间任务和心跳的问题。
猜你喜欢
  • 2016-09-16
  • 2023-03-03
  • 1970-01-01
  • 2015-03-31
  • 2023-04-09
  • 1970-01-01
  • 2019-03-29
  • 2017-06-23
相关资源
最近更新 更多