RabbitMQ 是不是会在有消息时为消费者调用回调函数?
Posted
技术标签:
【中文标题】RabbitMQ 是不是会在有消息时为消费者调用回调函数?【英文标题】:Does RabbitMQ call the callback function for a consumer when it has some message for it?RabbitMQ 是否会在有消息时为消费者调用回调函数? 【发布时间】:2012-02-27 10:21:08 【问题描述】:RabbitMQ 是否在有消息时为消费者调用回调函数,还是消费者必须轮询 RabbitMQ 客户端?
所以在消费者端,如果有 php 脚本,RabbitMQ 可以调用它并将消息/参数传递给它。例如如果在 shard 1 上提交了 rating 并且 aggregateRating 表在 shard 2 上,那么 shard 2 上的 RabbitMQ 消费者会触发脚本 aggRating.php 并传递插入到 shard 1 中的参数吗?
【问题讨论】:
库的实现方式不同。他们中的大多数都支持 basic.consume。如果您的 php 库没有,则需要编写自己的库。例如,您可以通过使用来自代理的消息的 python 脚本或 java 程序来驱动您的 php 脚本。 Python/Java 客户端根本不需要轮询,但它们需要与代理的稳定连接。代理将消息推送到 P/J 客户端。然后,客户端可以为每条消息调用您的脚本。详见 RabbitMQ 教程:rabbitmq.com/getstarted.html 我对 PHP 没有任何经验,对 PHP AMQP 客户端一无所知。我所说的关于 PHP 库的任何内容都只是一个有根据的猜测。我还没有在这里真正回答你的问题。顺便说一句,将来,您可能希望将此类问题发布到 RabbitMQ 讨论邮件列表。我认为我是唯一一个检查 SO 的 RabbitMQ 开发人员;但我们会认真回答邮件列表上发布的任何问题。 【参考方案1】:你想要的是basic.consume
,它允许代理向客户端推送消息。
也就是说,这些库的实现方式不同。他们中的大多数都支持basic.consume
,但由于所使用框架的固有限制,有些不支持(最值得注意的是许多其他客户端所基于的官方 RabbitMQ C 客户端)。
如果您的 PHP 库不支持basic.consume
,您要么必须使用轮询(不好),要么可以使用更完整的客户端之一来驱动脚本。例如,您可以编写一个从代理消费的 Python 或 Java 程序(因此,代理 推送 向它们传递)并且他们可以在收到新消息时调用脚本。 official tutorials 很好地介绍了 AMQP API,是一个很好的起点。
从大多数角度来看,这很有效,但它确实需要与代理的稳定连接。
如果对各种客户的能力有疑问,或者如果您需要更多指导,RabbitMQ Discuss 邮件列表是提问的好地方。开发人员会重点回答那里发布的任何问题。
【讨论】:
【参考方案2】:Pecl amqp 允许通过AMQPQueue::consume 方法使用消费功能。只需要传入回调函数,消息到达时就会执行。
【讨论】:
【参考方案3】:AMQPQueue::consume 方法现在是从 PHP AMQP 库 (http://www.php.net/manual/en/amqpqueue.consume.php) 版本 1.0 开始的 basic.consume 的“正确”实现.不幸的是,由于 PHP 是一种单线程语言,因此在同一进程空间中等待消息时,您不能做其他事情。如果您调用 AMQPQueue::consume 并向其传递回调,您的整个应用程序将阻塞并等待代理发送下一条消息,此时它将调用提供的回调函数。如果你想要一个非阻塞方法,你将不得不使用 AMQPQueue::get (http://www.php.net/manual/en/amqpqueue.get.php),它将轮询服务器以获取消息,并返回如果没有消息,则为布尔值 FALSE。
我不同意 scvatex 的建议,即使用单独的语言对这个问题使用“推送”方法。 PHP 不是 IO 驱动的,因此在消息到达时使用单独的语言调用 PHP 脚本似乎是不必要的复杂性:为什么不直接使用 AMQPQueue::consume 并让进程阻塞(等待消息),或者将所有回调中的逻辑或使回调运行单独的 PHP 脚本。
在我的工作中,我们将后者作为一个大规模的作业处理系统来完成,这样我们就可以隔离错误并保持父作业处理器运行,无论子进程发生什么。如果您想详细了解我们的设置方式和一些代码示例,我将非常乐意发布它们。
【讨论】:
以上是关于RabbitMQ 是不是会在有消息时为消费者调用回调函数?的主要内容,如果未能解决你的问题,请参考以下文章