Laravel отправить задание после завершения задания складывает память, а затем происходит сбой - PullRequest
2 голосов
/ 31 января 2020

То, что я хотел бы сделать, - это отправить задание, а затем продолжить отправку того же задания после завершения предыдущего, чтобы было непрерывное l oop отправляемого задания. Как указано в первом варианте, ранее он работал с драйвером очереди базы данных.

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

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

My config/horizon (local config совпадает с production):

'production' => [
            'supervisor-1' => [
                'connection' => 'redis',
                'queue' => ['arbitrage'],
                'balance' => 'auto',
                'processes' => 2,
                'tries' => 1,
            ],
            'supervisor-2' => [
                'connection' => 'redis',
                'queue' => ['trade'],
                'balance' => 'auto',
                'processes' => 4,
                'tries' => 1,
            ],
            'supervisor-3' => [
                'connection' => 'redis',
                'queue' => ['balance', 'trade_meta'],
                'balance' => 'auto',
                'processes' => 5,
                'tries' => 1,
            ],
            'supervisor-4' => [
                'connection' => 'redis',
                'queue' => ['notifications'],
                'balance' => 'auto',
                'processes' => 2,
                'tries' => 1,
            ],
        ],

Вариант 1: отправить новое задание в конце задания

По окончании задания handle() Я пересылаю его так, чтобы он работал непрерывно.

Это на самом деле работало нормально (процесс выполнялся неделями подряд) при использовании драйвера базы данных.

Задание:

class ArbitrageJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 1;
    public $timeout = 30;

    // Process things here

    ArbitrageJob::dispatch()->onQueue('arbitrage');
}

Вариант 2: отправить новое задание с помощью Queue:after

Задание:

class ArbitrageJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 1;
    public $timeout = 30;
}

Затем в AppServiceProvider:

Queue::after(function (JobProcessed $event) {
        ProcessArbitrage::dispatch()->onQueue('arbitrage');
});

То, что я вижу сейчас для обоих вариантов, так это то, что при каждом запуске происходит увеличение памяти (я регистрирую это через memory_get_usage(true)).

Первый запуск - 28 МБ, следующий - 32 МБ, и он продолжает увеличиваться до 122 МБ, а затем я получаю следующую ошибку: Illuminate\Queue\MaxAttemptsExceededException: App\Jobs\ArbitrageJob has been attempted too many times or run too long. The job may have previously timed out.

Вероятно, связано: в config/horizon Я установил memory_limit на 768 МБ, но похоже, что он выходит из строя намного раньше. Или это потому, что он ограничивает объем памяти до 128 МБ на одного работника?

Ответы [ 2 ]

0 голосов
/ 04 февраля 2020

Проблема была решена после перезагрузки компьютера. Не уверен почему, потому что я выполнил команды ниже. Я сейчас использую вариант 1, и все работает отлично.

php artisan config:cache
php artisan cache:clear
php artisan queue:restart
0 голосов
/ 31 января 2020

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

Вы должны использовать переключатели при использовании php artisan queue:work. Я предлагаю проверить это:

php Очередь ремесленника: работа - только попробуйте другие коммутаторы, которые могут работать только последние работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...