Laravel Очередь Horizon приостанавливается на одну минуту - PullRequest
4 голосов
/ 05 августа 2020

TL; DR Laravel Рабочие очереди Horizon go спать на 60 секунд после каждого обрабатываемого ими задания

У меня большое отставание в очереди Laravel Horizon. Рабочих много (maxProcesses установлено на 30), но когда я слежу за файлом журнала, вывод показывает, что он обрабатывает ровно 30 заданий в течение 2-3 секунд, а затем приостанавливает работу на целую минуту (подробнее или менее точно 60 секунд).

Есть идеи, почему это могло происходить? Я достиг некоторого ограничения ресурсов, из-за которого Horizon или Supervisor не работают?

Вот соответствующий раздел из моего горизонта. php файл конфигурации:

'environments' => [
        'production' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['high', 'default', 'low'],
                'balance' => 'false',
                'minProcesses' => 3,
                'maxProcesses' => 30,
                'timeout' => 1800,
                'tries' => 3
            ],

У меня есть точный такая же конфигурация в моей локальной среде, и моя локальная пропускная способность составляет ~ 600 заданий в минуту. В производстве он колеблется около 30 заданий в минуту.

Обновление по запросу @ Qumber

По большей части это не рабочие места. Это события, обрабатываемые одним или несколькими слушателями, большинство из которых очень просты. Например:


public function handle(TransactionDeleted $event)
{
    TransactionFile::where("transaction_id", $event->subject->id)->delete();
}

Вот некоторые конфигурации очереди:

'redis' => [
    'driver' => 'redis',
    'connection' => 'default',
    'queue' => env('REDIS_QUEUE', 'default'),
    'retry_after' => 1900,
    'block_for' => null,
],

Обновление по запросу @sykez

Вот конфигурация супервизора в local :

[program:laravelqueue]
process_name=%(program_name)s_%(process_num)02d
command=php /path/to/artisan queue:once redis --sleep=1 --tries=1

autostart=true
autorestart=true
user=adam
numprocs=3
redirect_stderr=true
stdout_logfile=/path/to/worker.log
stopwaitsecs=3600

Вот конфигурация супервизора в production :

[program:daemon-XXXXXX]
directory=/home/forge/SITE_URL/current/
command=php artisan horizon

process_name=%(program_name)s_%(process_num)02d
autostart=true
autorestart=true
user=forge
redirect_stderr=true
stdout_logfile=/home/forge/.forge/daemon-XXXXXX.log
stopwaitsecs=3600

Локальный супервизор запускает очередь напрямую, с "один раз "флаг, который должен загружать всю базу кода для каждого задания, а не запускаться как демон. Это, конечно, должно сделать его медленнее, а не в 20 раз быстрее ...

Другое обновление Благодаря некоторой помощи одного из основных разработчиков Laravel, мы смогли определить что все "зависшие" задания были широковещательными из событий, которые были настроены на широковещательную передачу после срабатывания. Мы используем Pusher в качестве движка вещания. Когда Pusher отключен (как в нашей локальной среде), задания завершаются sh немедленно, без паузы.

...