所以我使用beanstalk_console(https://github.com/ptrofimov/beanstalk_console)来监视我的beanstalkd队列,有时候,我会在埋藏状态下得到1或2个作业。这是由于我如何设置我的工作人员代码,我在保留工作时立即埋葬工作,如果一切顺利,则删除它(否则它会被埋没)。我还使用supervisord来管理多个队列工作者。下面的快速代码示例:
$pheanstalk = new Pheanstalk();
$pheanstalk->watch('tube');
while ($job = $pheanstalk->reserve()) {
$pheanstalk->bury($job);
$success = false;
// Process job here. Set $success to true if no errors were encountered
if ($success) {
$pheanstalk->delete($job);
}
}
现在我的问题:我注意到如果我使用beanstalk_console将我的埋藏工作移回他们指定的管道,那么随机时间我所有可用的工人将同时保留相同的工作(有趣的是,所有的一个不同的工作ID),导致重复工作。他们都会同时被埋葬,虽然beanstalk_console只会显示最新的埋没工作,所以我不确定是怎么回事。如果我在埋葬工作之前添加sleep(1)
之类的内容,那么只有1名工作人员保留这份工作而我不会重复工作。它几乎就像在预订后立即将工作埋入队列中。我的代码有问题吗?或者说beanstalk_console如何重新开始工作?
答案 0 :(得分:0)
当之前的问题似乎发生时,通常是因为工作脚本和工作人员之间的联系。 beanstalkd drop,所以这个工作会重新进入队列以便在其他地方获取。
还要确保捕获所有相关的异常并检查返回,以便您知道发生了什么。
答案 1 :(得分:0)
所以我重新审视了这个问题,看看它为什么会出现。 Beanstalk控制台使用do while循环来搜索剩余的作业,并且只有在因为没有找到任何更多的隐藏作业而抛出异常时才会退出此循环。
https://github.com/ptrofimov/beanstalk_console/blob/1.7.7/lib/include.php#L765
不幸的是,看起来循环可以捕获我立即埋葬的作业(就像在我的示例代码中一样),然后抛出异常,这可能导致同一个作业被多次处理。如果我有一个或多个工人等待工作也没关系。更多的工人只意味着更多的重复处理。