Работники Pheanstalk зарезервировали одну и ту же работу несколько раз, когда были немедленно похоронены
Поэтому я использую 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)
незадолго до того, как я похороню свою работу, только один работник резервирует работу, и я не получаю дублирующую работу. Это почти то же самое, что сразу же закопать работу после того, как резервирование поставит ее обратно в очередь. Что-то не так с моим кодом? Или что-то странное с тем, как beanstalk_console возвращает задания обратно?
2 ответа
Итак, я вновь обратился к этой проблеме и посмотрю, почему она возникает сейчас. Beanstalk Console использует цикл do while для поиска оставшихся рабочих мест и будет выходить из него только после того, как возникнет исключительная ситуация из-за того, что не будет найдено больше скрытых заданий.
https://github.com/ptrofimov/beanstalk_console/blob/1.7.7/lib/include.php
К сожалению, похоже, что цикл может перехватывать задания, которые я немедленно хороню (как в моем примере кода) задолго до того, как выдается исключение, что может привести к тому, что одно и то же задание обрабатывается более одного раза. Также не имеет значения, есть ли у меня 1 или более работников, ожидающих работы. Больше работников означает больше обработки дубликатов.
Когда кажется, что предыдущие проблемы, подобные этой, случаются, это обычно происходит потому, что связь между рабочим скриптом и beanstalkd обрывается, и поэтому задание возвращается в очередь, которую нужно забрать в другом месте.
Также обязательно перехватывайте все соответствующие исключения и проверяйте возвраты, чтобы вы знали, что происходит.