一段时间后,blpop停止处理队列

时间:2014-12-18 06:03:10

标签: php redis

在我的组织中,我们有许多redis工作人员来完成我们的关键任务。通常,一天一到两次,我们的工作人员就会停止处理队列。

代码基本上如下所示:

while ($item = $redis->blpop(array('someQueue', 'anotherQueue'), 3600)) {
    someFunction();
}

如果你看到,代码方面的情况并不多,但每隔一段时间,队列就会开始构建,而工作人员不会从队列中弹出任何项目。设置blpop的超时时间根本没用,因为我们假设问题出在redis客户端连接上。

目前,我们已经建立了一些听众,当队列建立时我们会提醒我们,然后我们重新启动工作人员,但问题仍然存在。我们还可以为我们的redis客户端设置超时,但这又不是一个理想的解决方案。

  • 还有其他人遇到过这个吗?
  • 可能是什么问题?
  • 我们做错了吗?

我们的问题与Error in implementing message queue using redis, error in using BLPOP类似,但我们没有收到任何错误。工人突然停止了。

信息

Redis服务器:2.8.2

PHP Redis:phpredis

更新#1

已经运行很长时间的工作人员已停止处理队列。运行CLIENT LIST后,我们发现这些工作人员与其他工作人员相比空闲时间较长,他们的标记设置为N而不是b。这背后可能是什么原因?

更新#2

问题在于someFunction()。有一段代码导致函数无法返回控制权,因为客户端长时间闲置,因此运行CLIENT LIST时出现“N”标志。

2 个答案:

答案 0 :(得分:5)

我建议验证是否存在问题并将问题报告回Redis项目作为问题如果您找到了服务器端。但是,即使在堆栈的其他部分中,以下步骤也可以帮助您解决问题(很可能,因为没有类似于上述问题的已知问题)。

检查发生了什么的步骤:

  1. 等待一个客户停止。
  2. 使用LLEN命令验证列表中是否存在实际元素。
  3. 检查CLIENT LIST是否确实列出了您的客户端,执行阻止弹出窗口(您将看到命令名称),并检查回复的大小以查看是否是您的客户端实际上并没有消费它得到的回复。
  4. 随机评论:

    1. Redis 2.8.2。太旧了,建议升级。
    2. phpredis可能有可能导致此问题的错误,如果它与Redis服务器一样旧。

答案 1 :(得分:-1)

我们遇到了另一个问题:如果应用服务器暂时失去与Redis服务器的连接,Redis句柄将变为无效(顺便说一句,我们希望这一点 - 这不是一个错误)。虽然您的问题不同,但我们使用的解决方法也可能对您有用:

您可以这样做:

while (true) {
    // The factory method below will check whether handle is valid. If not, create a new one and return
    $redis = MyRedisFactory::getInstance(); 
    $item = $redis->blpop(array('someQueue', 'anotherQueue'), 3600);
    someFunction();
}