我正在尝试使用Redis构建消息队列。 每当客户端发送新数据时,它们都会添加到列表中。使用redis实现消息队列时出错,使用BLPOP时出错
这里是它的代码
$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
根据该文件,如果列表为空的话,直到另一个客户端BLPOP/BRPOP块连接执行LPUSH或RPUSH操作反对其中一个键。 但是这不是在我的情况发生。 在我的情况下,一旦brpop阻塞连接,即使新数据到达列表中,它也不会再次侦听。
我应该做些什么改变才能使它工作?
我会建议确保两个脚本连接到同一个数据库上的同一个Redis实例。它应该工作。另外,设置无限超时是一种不好的做法。等待10秒钟,处理/忽略代码中的空结果会更好。 –
是的..两个脚本连接到同一个数据库上的同一个redis实例。正如我所提到的,它在几分钟内运作良好。但等待几分钟后,它会阻止连接,并且不会再次收听。关于等待10秒,我们可以这样做,但我认为BLPOP具有一些功能,通过该功能,每当新数据到达列表中时,从脚本都会发现它。同时提出不必要的空请求会增加服务器负载 –
如果每10秒检查一次,则每20或30 * 10亿个周期增加一些额外的指令。这并不重要,但会使您的服务更加可靠。迪迪埃是对的;这是阻止Redis中弹出窗口的非常标准的做法。 – Jimothy