如何在长期工作的消费者中提供与Pika的并发性?

时间:2012-06-13 20:49:51

标签: python concurrency rabbitmq pika

简短版本:如何在远程过程调用情况下阻止阻止Pika?

长版:

Pika的例子都没有证明我的用例。

我有一个Tornado服务器,通过AMQP(RabbitMQ,Pika)与其他进程/机器通信。这些其他过程的定义不是很明确,但它们大部分都会返回数据(参见RPC example on RabbitMQ's website)。有时,进程可能需要花费很长时间来处理大量信息,但它不应该完全阻止进程占用较小的请求。或者远程服务器可能阻塞,因为它发出了Web请求。可以把它想象成一个Web服务器,但是使用AMQP而不是HTTP。

由于Pika文档声称它不是线程安全的,我无法将连接传递给多个线程(或者进程,就此而言)。我想要做的是启动一个新进程,并将一个套接字事件(对于该程序的管道)添加到Pika IOLoop,就像我可以使用Tornado一样。 Pika IOLoop与Tornado IOLoop有很大的不同,它似乎不支持添加多个处理程序;它似乎在一个插座上使用一个“轮询器”进行操作。

我想避免为此软件包要求Tornado软件包,因为我只会使用IOLoop。这不是不可能的,但我想看看我的其他选择是什么,或者是否通过某种方式连接多个Pika IOLoops / Poller解决了我的问题。 RabbitMQ的文档说,工人通常可以通过添加更多来“扩大规模”。我想避免为每个请求创建一个连接(如果它们快速进入)。

1 个答案:

答案 0 :(得分:0)

根据您的描述,我相信您需要不同的通信模型或需要多个Pika IOLoops / Pollers / Redundant Connections。

听起来像是来自文档和其他网站,Pika中的RPC总是一个阻塞语句,无法在线程之间传递。请参阅http://www.rabbitmq.com/tutorials/tutorial-six-python.html作者指出,一旦您实际调用ioloop,Pika中的RPC本身就会阻塞。

"When in doubt avoid RPC. If you can, you should use an asynchronous pipeline - instead of RPC-like blocking"

如果要在完成之前继续在同一连接上发送多个RPC调用,则需要使用不同的异步模型。在完成之前对同一连接进行多次RPC调用并不是RPC模型的常规实现,尽管从技术上讲它并不是禁止的(http://pic.dhe.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.progcomm%2Fdoc%2Fprogcomc%2Frpc_mod.htm)。我不认为Pika使用这个模型,虽然它通过回调确实有异步支持(不是你想要的我认为)。

如果您只是希望能够轻松地动态生成新连接,则可以在连接上使用线程或进程包装器,您可以在其他上下文中创建并阻止RPC,并推送到公共队列,主线程可以监控。 Tornado可能会给你这个,但我同意这有点过分,并且制作这样的连接包装应该不是那么困难,因为我在不到100行的Python中为其他I / O操作做了类似的事情(请参阅“线程包装器版本的队列包”。我认为你已经看到了这种可能性,但是基于你对多个IOLoops的讨论。