Pheanstalk 工人在立即埋葬时多次保留相同的工作
Pheanstalk workers reserving same job multiple times when buried immediately
所以我使用 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 恢复工作的方式有些奇怪?
当以前类似的问题似乎发生时,通常是因为 worker 脚本和 beanstalkd 之间的连接断开,因此作业返回到队列中以在其他地方拾取。
还要确保捕获所有相关异常并检查 returns 以便了解发生了什么。
所以我重新审视了这个问题,看看为什么现在会出现这个问题。 Beanstalk Console 使用 do while 循环来搜索剩余的作业,并且只会在因找不到更多隐藏的作业而抛出异常时退出此循环。
https://github.com/ptrofimov/beanstalk_console/blob/1.7.7/lib/include.php#L765
不幸的是,循环似乎可以在抛出异常之前捕获我立即隐藏的作业(就像在我的示例代码中一样),这可能导致同一作业被处理多次。我是否有 1 个或多个工人在等待工作也无关紧要。更多的工人意味着更多的重复处理。
所以我使用 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 恢复工作的方式有些奇怪?
当以前类似的问题似乎发生时,通常是因为 worker 脚本和 beanstalkd 之间的连接断开,因此作业返回到队列中以在其他地方拾取。
还要确保捕获所有相关异常并检查 returns 以便了解发生了什么。
所以我重新审视了这个问题,看看为什么现在会出现这个问题。 Beanstalk Console 使用 do while 循环来搜索剩余的作业,并且只会在因找不到更多隐藏的作业而抛出异常时退出此循环。
https://github.com/ptrofimov/beanstalk_console/blob/1.7.7/lib/include.php#L765
不幸的是,循环似乎可以在抛出异常之前捕获我立即隐藏的作业(就像在我的示例代码中一样),这可能导致同一作业被处理多次。我是否有 1 个或多个工人在等待工作也无关紧要。更多的工人意味着更多的重复处理。