Задание выполнялось слишком много раз или выполнялось слишком долго

У меня есть работа, которая локально работает безупречно, но на производстве я сталкиваюсь с проблемами, когда она не работает. Я охватил весь handle() с помощью try/catch, и я не вижу, чтобы что-либо было зарегистрировано в Bugsnag, несмотря на то, что многие другие исключения не были развернуты.

public function handle() {
    try {

        // do stuff

    } catch (\Exception $e) {
        Bugsnag::notifyException($e);

        throw $e;
    }
}

Согласно Laravel Horizon, это задание очереди выполняется в течение 0.0026001930236816406 секунд, и я никогда не вижу, чтобы оно работало, и никогда не вижу никаких других ошибок в таблице failed_jobs, связанных с этим заданием.

конфигурация / queue.php

    'redis' => [
        'driver' => 'redis',
        'connection' => 'default',
        'queue' => 'default',
        'retry_after' => (60 * 10), // 10 minutes
        'block_for' => null,
    ],

конфигурация / Horizon.php

'environments' => [
    'production' => [
        'supervisor'        => [
            'connection'    => 'redis',
            'queue'         => [
                'default',
            ],
            'balance'       => 'auto',
            'processes'     => 10,
            'tries'         => 3,

            // 10 seconds under the queue's retry_after to avoid overlap
            'timeout'       => (60 * 10) - 10, // Just under 10 mins
        ],

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

Расследование до сих пор

  • Я ожидаю, что смогу выполнить запрос:
SELECT DISTINCT exception, COUNT(id) as errors
FROM failed_jobs 
WHERE payload LIKE '%[TAG-JOB-HAS]%' 
GROUP BY exception;

Чтобы увидеть больше, чем это сообщение об ошибке:

Job has been attempted too many times or run too long

но это все, что я вижу.

  • Панель управления Laravel Horizon показывает, что рассматриваемое задание выполняется менее 1 секунды, поэтому я знаю, что на самом деле время ожидания не истекло.

Вы пробовали регистрировать отладочные операторы, чтобы доказать, что задание действительно было выполнено? Можете ли вы включить дополнительную информацию о том, что на самом деле делает задание, и, возможно, немного кода? Это могло произойти из-за того, что не генерировались исключения.

Travis Britz 04.11.2018 02:52

«... но в процессе производства я сталкиваюсь с проблемами, когда это не работает» - что именно не работает? Вы видите ошибку в логах?

Laurence 04.11.2018 09:57

Просто подумайте, это строка Bugsnag::notifyException($e) вызывает исключение, заставляя Laravel повторно запросить вашу работу для повторной попытки?

Jamesking56 05.11.2018 18:27

Что такое "// do stuff"? Делает ли он что-нибудь странное, например, call exit () или die ()?

Travis Britz 06.11.2018 12:28

Вы перезапустили очередь после добавления try catch к функции handle?

Elie 06.11.2018 14:28

Я тоже получил эту ошибку, и моя настройка очереди добавляет параметры tries: php artisan queue:work --tries=3, и вы должны проверить это в документе laravel.com/docs/5.5/queues#failed-job-events

bangnokia 06.11.2018 19:10

Попробуйте поймать \Throwable вместо \Exception. \Exception не отлавливает внутренние ошибки PHP. Это тебе что-нибудь даст? Также, как уже упоминалось, убедитесь, что проблема не в Bugsnag.

patricus 08.11.2018 03:30
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
23
7
29 071
3

Ответы 3

Попробуйте поймать исключение в неудачном методе, заданном laravel

/**
* The job failed to process.
*
* @param  Exception  $exception
* @return void
*/
public function failed(Exception $exception)
{
    // Send user notification of failure, etc...
}

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

Не могли бы вы рассказать подробнее? Например, где можно создать эту функцию и на какую документацию вы тоже ссылаетесь? Или вы вручную выполняете из AppServiceProvider?

Yevgeniy Afanasyev 14.10.2021 04:23

Согласно документация, вы можете справиться с ошибкой задания двумя распространенными способами:

  • использование событий неудачной работы
  • с использованием метода failed().

В первом случае вы можете обрабатывать все задания методом Queue::failing(). Вы получите событие Illuminate\Queue\Events\JobFailed в качестве параметра, и оно содержит исключение.

В другом случае вы можете использовать метод failed(), он должен находиться рядом с вашим методом handle(). Вы также можете получить Exception $exception в качестве параметра.

Пример:

public function failed(\Throwable $exception)
{
    // Log failure
}

Надеюсь это поможет.

У меня такая же проблема

Я исправил это, увеличив параметр retry_after

убедитесь, что значение retry_after больше, чем время, необходимое для выполнения задания

в файле конфигурация / queue.php

    'connections' => [

    'sync' => [
        'driver' => 'sync',
    ],

    'database' => [
        'driver' => 'database',
        'table' => 'jobs',
        'queue' => 'default',
        'retry_after' => 9000,
    ],

Вы знаете, почему параметр retry_after не влияет на очередь на моем локальном компьютере, но влияет на очередь на сервере?

mark DE Jong 18.12.2019 15:28

Другие вопросы по теме