当RabbitMQ有消息需要传递给消费者时,它会调用回调函数吗?

17

RabbitMQ在有消息需要传递给消费者时,会调用回调函数还是消费者必须轮询RabbitMQ客户端?

因此,在消费者方面,如果有一个PHP脚本,RabbitMQ能否调用它并将消息/参数传递给它。例如,如果在分片1上提交了评分,并且aggregateRating表位于分片2上,那么分片2上的RabbitMQ消费者是否会触发名为aggRating.php的脚本并传递在分片1中插入的参数?


1
这些库的实现方式不同。它们中的大多数都支持basic.consume。如果你的PHP库没有这个功能,你需要自己编写。例如,你可以通过一个消费代理从经纪人那里获取消息来驱动你的PHP脚本,这个消费代理可以是Python脚本或Java程序。 - scvalex
Python/Java客户端完全不需要轮询,但是它们需要与代理保持稳定的连接。代理将向P/J客户端推送消息。然后,客户端可以为每个消息调用您的脚本。有关详细信息,请参阅RabbitMQ教程:http://www.rabbitmq.com/getstarted.html - scvalex
1
我没有PHP方面的经验,也不了解PHP AMQP客户端。我对PHP库所说的一切只是基于我的猜测。我并没有真正回答你的问题。顺便说一句,在将来,你可能想把这样的问题发布到RabbitMQ讨论邮件列表中。我认为我是唯一会检查SO的RabbitMQ开发人员;但我们会回答在邮件列表上发布的任何问题。 - scvalex
3个回答

12
AMQPQueue::consume方法是PHP AMQP库版本1.0中basic.consume的“正式”实现。然而,由于PHP是单线程语言,在同一进程空间中等待消息时无法同时执行其他任务。如果调用AMQPQueue::consume并传递回调函数,整个应用程序将被阻塞,等待代理发送下一个消息,此时它将调用提供的回调函数。如果您需要非阻塞方法,则必须使用AMQPQueue::get,它将轮询服务器以获取消息,并在没有消息时返回布尔值FALSE。
对于scvatex建议使用另一种语言来解决此问题的观点,我持不同意见。因为PHP不是基于IO驱动的语言,因此使用另一种语言调用PHP脚本来处理到达的消息似乎是不必要的复杂性:为什么不直接使用AMQPQueue::consume让进程阻塞(等待消息),并将所有逻辑放在回调函数中,或者让回调函数运行一个单独的PHP脚本。
我们在工作中作为一个大规模作业处理系统使用后者,以便我们可以隔离错误并保持父作业处理器运行,无论子进程中发生什么情况。如果您想了解我们如何设置这个过程以及一些代码示例的详细描述,我很乐意发布它们。

10
你需要的是basic.consume,它允许代理向客户端推送消息。但是,这些库的实现方式不同。大多数库都支持basic.consume,但由于所用框架的固有限制,有些库不支持(尤其是很多其他客户端基于的官方RabbitMQ C客户端)。如果你的PHP库不支持basic.consume,你只能使用轮询(不好),或者使用更完整的客户端之一来驱动脚本。例如,你可以编写一个Python或Java程序从代理中消费(因此,代理将传递交付给它们),并在接收到新消息时调用脚本。官方教程是AMQP API的很好介绍和入门指南。这种方法在大多数情况下都很有效,但需要与代理保持稳定的连接。
如果您对各种客户端的能力存在疑问,或者需要更多指导,RabbitMQ Discuss 邮件列表是一个很好的提问场所。开发人员会特别回答在那里发布的任何查询。

0

Pecl amqp 允许使用 AMQPQueue::consume 方法的消费功能。您只需要在其中传递回调函数,当消息到达时它将被执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接