Несколько слушателей очереди будут выполнять одно и то же задание в нескольких процессах

У меня есть простое веб-приложение, написанное с использованием платформы Laravel 4.2. Я настроил компонент очереди Laravel для добавления новых элементов очереди на локально работающий сервер beastalkd.

По сути, есть POST-маршрут, который добавит элемент в трубочку beanstalkd.

Затем я установил диспетчер для запуска artisan queue:listen как три отдельных процесса. Проблема, которую я вижу в том, что разные queue:listen процессы будут заканчиваться порождением где-то от одного до трех queue:worker процессы только для одной вставленной работы.

Конечным результатом является то, что одна работа, вставленная в очередь, иногда обрабатывается несколькими работниками одновременно, чего я, очевидно, пытаюсь избежать.

Код задания относительно прост:

<?php

use App\Repositories\URLRepository;

class ProcessDataJob {
private $urls;

public function __construct(URLRepository $urls)
{
$this->urls = $urls;
}

public function fire($job, $data)
{
$input = $data['post'];

if (!isset($data['post']) && !is_array($data['post'])) {
Log::error('[Job #'.$job->getJobId().'] $input was empty inside CreateAuditJob. Deleting job. Quitting. Bye!');
$job->delete();
return false;
}

//
// ... code that will take a few hours to run.
//

$job->delete();
Log::info('[Job #'.$job->getJobId().'] ProcessDataJob was successful, deleting the job!');
return true;
}
}

Самое интересное, что большинство (дублированных) работников очереди не удаются при удалении задания, оставленного в журнале ошибок:

exception 'Pheanstalk_Exception_ServerException' with message 'Job 3248 NOT_FOUND: does not exist or is not reserved by client'

Ttr (время выполнения) установлено на 172800 секунд (или 48 часов), что намного больше, чем время, необходимое для выполнения задания.

9

Решение

что такое работа time_to_run в очереди? Если выполнение задания занимает больше времени, чем time_to_run секунд, задание автоматически ставится в очередь и становится доступным для запуска следующим работником.

Зарезервированное задание имеет время time_to_run для удаления, отпускания или касания. призвание touch() перезапускает таймер тайм-аута, чтобы работники могли использовать его, чтобы дать себе больше времени для завершения. Или используйте достаточно большое значение в очереди.

Я нашел документ протокола beanstalkd полезным
https://github.com/kr/beanstalkd/blob/master/doc/protocol.md

3

Другие решения

Поскольку вы работаете с Laravel, проверьте ваш queue.php конфигурационный файл.

Изменить TTR значение от 60 (по умолчанию) до чего-то еще, что лучше для вас.

    'beanstalkd' => array(
'driver' => 'beanstalkd',
'host'   => 'localhost',
'queue'  => 'default',
'ttr'    => 600, //Example
),
2