У меня есть простое веб-приложение, написанное с использованием платформы 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 часов), что намного больше, чем время, необходимое для выполнения задания.
что такое работа time_to_run в очереди? Если выполнение задания занимает больше времени, чем time_to_run секунд, задание автоматически ставится в очередь и становится доступным для запуска следующим работником.
Зарезервированное задание имеет время time_to_run для удаления, отпускания или касания. призвание touch()
перезапускает таймер тайм-аута, чтобы работники могли использовать его, чтобы дать себе больше времени для завершения. Или используйте достаточно большое значение в очереди.
Я нашел документ протокола beanstalkd полезным
https://github.com/kr/beanstalkd/blob/master/doc/protocol.md
Поскольку вы работаете с Laravel, проверьте ваш queue.php
конфигурационный файл.
Изменить TTR значение от 60 (по умолчанию) до чего-то еще, что лучше для вас.
'beanstalkd' => array(
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'ttr' => 600, //Example
),