【问题标题】:RabbitMQ - How to check if queue is empty?RabbitMQ - 如何检查队列是否为空?
【发布时间】:2015-09-08 14:19:17
【问题描述】:

我有一个抽象 RabbitMQ 服务器的 Web 服务接口(不要问我为什么,我知道这是一个不必要的步骤,但我必须这样做)。也就是说,我通过 Web 服务调用而不是直接通过 amqp 从队列中轮询消息。

通过basic.consumer 消费会阻塞执行线程,直到队列中有消息。这使得 Web 服务不会返回。

说明代码:

    $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
    $channel = $connection->channel();

    $channel->queue_declare(QUEUE_NAME, false, true, false, false);
    $ret = array('body' => '');

    $callback = function($msg) use ($channel, &$ret) {
        $ret['body'] = $msg->body;
        /*
        Here I would basic.cancel the consumer if there were no messages in the queue
        */
    };

    $channel->basic_consume(QUEUE_NAME, 'tag', false, true, false, false, $callback);

    if (count($channel->callbacks)) {
        $channel->wait(); // blocks here...
    }

    return $ret;

【问题讨论】:

标签: php rabbitmq php-amqplib


【解决方案1】:

如果要获取队列的大小,可以用php-amqlib调用queue_declare,return的第二个参数是队列中的消息数。

  list($queue, $messageCount, $consumerCount) = $channel->queue_declare(QUEUE_NAME, true);

在调用 queue_declare() 方法时,将 $passive 参数设置为 true 很重要

【讨论】:

    【解决方案2】:

    我想做的事情是通过basic.get实现的。

    在 php-amqlib 中:

    $channel->basic_get(QUEUE_NAME, true); // the second arg is no_ack.

    第二个参数表示该消息不需要确认。也就是说,您不必将消息“标记”为已读,以便 RabbitMQ 自信地将其出列。排除它(设置它 = false)不会弹出顶部消息。

    为什么要这么麻烦?

    我将 RabbitMQ 代码包装在一个 http web 服务中。这不是一个好主意(至少对于我的用例而言)。当 web 服务返回时,rabbitmq 连接终止,未(尚未)确认的消息被重新排队返回队列。因此,如果您必须采用 http 包装器,请确保将 rabbitmq 连接的生命周期与 http 请求的生存时间隔离开来。但是,我没有尝试过。

    【讨论】:

    • 如果你还想得到队列的大小,当你声明交换时,它会返回一个具有当前队列大小的数据结构
    • AMQP 参考提供:“如果设置了此字段,则服务器不期望消息的确认。也就是说,当消息传递给客户端时,服务器假定传递将成功并立即将其出列。此功能可能会提高性能,但会以可靠性为代价。如果客户端在传递给应用程序之前死亡,消息可能会丢失。”。如果你不设置它,你必须确认你收到的消息。
    • 我不明白这个答案的后半部分(标题下方)。如果与答案无关,建议编辑或删除。
    猜你喜欢
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 2023-04-08
    • 2021-02-01
    相关资源
    最近更新 更多