Python amqp 破管错误

4 投票
2 回答
2409 浏览
提问于 2025-04-18 00:41

简单问题:

我需要担心两个独立的应用同时使用同一个通道与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所说,这和线程有关。你不能在多个线程中重复使用同一个连接,每个线程都需要打开一个新的连接。

撰写回答