做阻止空队列的消费者

时间:2015-02-16 16:04:15

标签: php rabbitmq amqp consumer

具体细节信息

我有用PHP编写的消费者,它试图消费消息。我的目标很简单 - 如果队列中没有消息,则释放执行并继续,考虑到没有"没有检索到数据"。

当前的想法

我尝试了AMQP_NOWAIT标志,如:

$flag = AMQP_NOWAIT;
$this->queue->consume($callbackFunction, $flag, $this->consumerTag);

它没有用。到目前为止,我有解决方法,比如 - 我宣布\AMQPConnection的连接超时,比如说,5秒,然后以这种方式捕获它:

try {
    $this->consumer->consume($this->consumer->getReadMessageCallback($notifications, $requeue));
} catch (\AMQPConnectionException $connectionException) {
    //based on timeouts. Are there other ways to interrupt empty queue consuming? AMQP_NOWAIT fails, does nothing:
    return [];
}

但是,这是一个非常" hacky"这样做的方式。它为我工作,但是:

  • 仍然阻止timeout
  • 的代码
  • 如果我收到太多信息(即终止胜利直到超时结束),显然会失败。
  • 更多,它甚至没有记录,所以依靠这应该是最后的手段。

下一步 - 我在队列创建时尝试了AMQP_IFEMPTY | AMQP_PASSIVE。问题是 - 如果那里没有消息,它将删除队列,并且在尝试从那里获取消息时会引发异常(我可能会捕获)。但后来出现了一个问题 - 队列被立即删除,我甚至无法在那里添加消息。

问题

从空队列中读取消息确实是一个常见问题,因此我确信它应该是一种在适当的问题上解决它的方法。那么,我该怎么做?

是的,手动链接为/pl/,因为没有" en"链接。但无论如何,它的可读性或多或少都是可读的。

1 个答案:

答案 0 :(得分:2)

如果您需要弄清楚队列是否为空,您可以调用幂等的AMQPQueue::declare(),并在结果中返回队列中的消息计数。请注意,该数字并不准确(请参阅why)。

此外,您只需拨打AMQPQueue::get()(行为与管理工具相同)。

之后,正如您所尝试的那样,您可以将AMQPConnection::setReadTimeout()设置为某个较低的值(在本地网络1秒内就足够了),然后调用AMQPQueue::consume()并捕获超时异常(如果消费者)等了太久。

关于糟糕的文档,请参阅此问题的答案:Where can i find the php-amqp documentation