Python amqp 破管错误
简单问题:
我需要担心两个独立的应用同时使用同一个通道与RabbitMQ通信,从而导致“管道损坏错误”吗?(或者说,线程和两个或多个独立应用是不同的情况吗?)
背景:
我写了一些应用,其中一个(io-server)在我的其他应用看来像个服务器,而在RabbitMQ服务器看来则像个客户端。
现在,一切正常运行大约10分钟后,我的io-server就崩溃了。以下是错误追踪的最后部分:
File "/usr/local/lib/python2.7/dist-packages/amqp-1.4.2-py2.7.egg/amqp/transport.py", line 163, in write_frame
frame_type, channel, size, payload, 0xce,
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
error: [Errno 32] Broken pipe
这是RabbitMQ日志中相关的部分:
=ERROR REPORT==== 31-Mar-2014::12:29:53 ===
AMQP connection <0.22183.0> (running), channel 1 - error:
{amqp_error,unexpected_frame,
"expected content header for class 60, got non content header frame instead",
'basic.publish'}
=INFO REPORT==== 31-Mar-2014::12:30:23 ===
closing AMQP connection <0.22183.0> (127.0.0.1:43367 -> 127.0.0.1:5672)
根据我在网上的搜索,最有希望的答案是这里:
...
So yes, RabbitMQ closes the connection due to a connection-level error
with frame interleaving.
...
* Avoid publishing on *the same* channel from multiple threads
* Synchronize publishing in your own code
我可以让我的应用同步发布消息。但我怎么能保证所有应用都能同步运行呢?我真的有必要这样做吗?
2 个回答
0
我需要担心两个独立的应用程序使用同一个通道吗?
不需要。这里说的“通道”指的是你们共享的一个 Channel
对象。如果不同的应用程序(进程)不共享内存,它们会各自有不同的通道。
线程和两个或多个独立的应用程序有什么不同吗?
有的。你使用的 amqp 库并不是线程安全的。如果你在“IO 服务器”中跨不同的线程共享一个 Channel()
对象,这就会出现问题。不过,如果你的服务器是单线程的,并且你运行多个并行实例,那就没问题。
我建议你保持简单,不要在你的服务器应用中使用线程。假设你的 IO 服务器接受来自其他应用的 HTTP 连接,可以依靠 nginx+uwsgi 来处理并行请求。
0
我也遇到过这个问题,正如@istepaniuk所说,这和线程有关。你不能在多个线程中重复使用同一个连接,每个线程都需要打开一个新的连接。