1

我正在尝试使用 Redis 构建消息队列。每当客户端发送新数据时,它们都会被添加到列表中。

这是它的代码

$client->lPush("my_queue", $data);

现在有一个单独的脚本slave.php弹出新到达的数据并对其进行处理。slave.php 的代码

while (true) {
   list($queue, $message)  = $client->brPop(["my_queue"], 0);

    /*
    Logic to process the data
    */
}

我已经修改了 apache 启动脚本,以便 slave.php 应该使用 apache 启动和停止。它运作良好。但是在等待几分钟后,brPop 停止侦听并显示如下错误消息:

Uncaught exception 'Predis\Connection\ConnectionException' with message 'Error while reading line from the server [tcp://127.0.0.1:6379]' in /var/www/api/lib/predis-0.8/lib/Predis/Connection/AbstractConnection.php:139
Stack trace:
#0 /var/www/api/lib/predis-0.8/lib/Predis/Connection/StreamConnection.php(205): Predis\Connection\AbstractConnection->onConnectionError('Error while rea...')
#1 /var/www/api/lib/predis-0.8/lib/Predis/Connection/AbstractConnection.php(128): Predis\Connection\StreamConnection->read()
#2 /var/www/api/lib/predis-0.8/lib/Predis/Connection/AbstractConnection.php(120): Predis\Connection\AbstractConnection->readResponse(Object(Predis\Command\ListPopLastBlocking))
#3 /var/www/api/lib/predis-0.8/lib/Predis/Client.php(227): Predis\Connection\AbstractConnection->executeCommand(Object(Predis\Command\ListPopLastBlocking))
#4 /var/www/api/lib/slave.php(7): Predis\Client->__call('brPop', Array)
#5 /var/www/api/lib/slave.php(7): Predis\Client->brPop(Array, 0)
#6 {main}
 thrown in /var/www/api/lib/predis-0.8/lib/Predis/Connection/AbstractConnection.php on line 139

根据文档,如果 list 为空,则 BLPOP/BRPOP 会阻止连接,直到另一个客户端对其中一个键执行 LPUSH 或 RPUSH 操作。但这在我的情况下没有发生。在我的情况下,一旦 brpop 阻止连接,即使新数据到达列表中,它也不会再次收听。

我应该进行哪些更改才能使其正常工作?

4

3 回答 3

1

它现在对我有用,但我不确定这是否是正确的方法。现在我正在捕获错误并在连接失败的情况下递归调用该函数。我的新 slave.php 看起来像这样:

function process_data()
{
    try {
        $client = new \Predis\Client();

        require_once("logger.php");

        while (true) {
            list($queue, $message) = $client->brPop(["bookmark_queue"], 0);
            // logic
        }
    } catch (Exception $ex) {
        $error = $ex->getMessage();
        log_error($error, "slave.php");
        process_data(); // call the function recursively if connection fails
    }
}
process_data(); // call the function
于 2014-01-08T06:20:49.040 回答
0

添加?read_write_timeout=-1到您的连接字符串。

于 2016-11-28T11:34:43.477 回答
0

问题不在于您的 Redis 配置,但您必须更改php.ini设置并设置

default_socket_timeout = 90 //Or whatever you would like to set

PHP 在达到最大套接字超时时断开套接字。

于 2020-04-02T15:43:59.170 回答