Другое

Laravel 12: cron‑задачи не работают после обновления

Почему cron‑задачи Laravel 12 не запускаются после обновления? Узнайте причины и как исправить конфигурацию и миграцию кода.

Laravel 12 Cron Job не работает после обновления с Laravel 10

Я обновил приложение до Laravel 12.39 (PHP 8.3), и мои запланированные задачи перестали выполняться. Та же конфигурация cron работала без проблем в Laravel 10.

Текущая конфигурация cron

В cPanel у меня есть следующая запись cron:

bash
* * * * * /usr/local/bin/php /home/my-project/public_html/artisan schedule:run > /dev/null 2>&1

Конфигурация Kernel в Laravel 12

В файле app/Console/Kernel.php расписание задано так:

php
<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * Define the application's command schedule.
     */
    protected function schedule(Schedule $schedule): void
    {
        // Continuous Queue Processing
        $schedule->command('queue:work --tries=3')
            ->runInBackground()
            ->withoutOverlapping()
            ->evenInMaintenanceMode()
            ->everyMinute();

        if (app()->isProduction()) {
            // Clear views every five minutes
            $schedule->command('view:clear', ['--quiet'])
                ->withoutOverlapping()
                ->everyFiveMinutes();
        }
    }

    /**
     * Register the commands for the application.
     */
    protected function commands(): void
    {
        $this->load(__DIR__ . '/Commands');

        require base_path('routes/console.php');
    }
}

Вопрос

Правильно ли настроен мой cron в cPanel, или в коде Laravel 12 есть проблема, которую нужно исправить? Та же настройка cron работала отлично в Laravel 10, но после обновления до Laravel 12.39 запланированные задачи не запускаются. Любая помощь в устранении этой проблемы будет очень ценна.

Проблема, с которой вы столкнулись при работе cron‑задач в Laravel 12 после обновления с Laravel 10, скорее всего связана с существенными архитектурными изменениями, которые произошли в Laravel 11 и 12, особенно в отношении ядра консоли и системы планировщика задач. Конфигурация cron выглядит корректной, но структура кода должна быть обновлена в соответствии с новыми конвенциями Laravel 12.


Содержание


Изменения в ядре консоли в Laravel 12

Laravel 12 претерпел значительные архитектурные изменения по сравнению с Laravel 10, особенно в том, как обрабатываются запланированные задачи. Самое критичное изменение — запланированные задачи больше не могут быть определены в традиционном файле app/Console/Kernel.php, как это было в Laravel 10.

Согласно заметкам к выпуску Laravel 11, «запланированные задачи теперь могут быть определены напрямую в файле routes/console.php вашего приложения, устраняя необходимость отдельного класса ядра консоли». Это изменение было перенесено и в Laravel 12.

Проблема в том, что при обновлении с Laravel 10 до 12 фреймворк ожидает, что вы адаптируете свой код под эти новые конвенции. Многие разработчики сообщают о похожих проблемах:

Однако я уже решил свою проблему, перенеся код планировщика в routes/console.php, так как это, по-видимому, новое рекомендуемое место для определения расписания в Laravel 11. В laravel 12 команда не работает из kernel.php, я переместил свою команду в bootstrap/app.php, и теперь всё работает без проблем.
Пользователь StackOverflow о проблемах с планировкой в Laravel 12

Проверка конфигурации cron

Конфигурация cron, которую вы используете, на самом деле корректна согласно официальной документации Laravel:

bash
* * * * * /usr/local/bin/php /home/my-project/public_html/artisan schedule:run > /dev/null 2>&1

Документация Laravel подтверждает, что это стандартный формат запуска планировщика Laravel. Cron должен запускаться каждую минуту, а Laravel сам управляет временем выполнения отдельных задач.

Примечание: На большинстве операционных систем cron‑задачи ограничены запуском не чаще, чем раз в минуту.
Документация по планировке задач Laravel 12.x

Лучшие практики работы с воркерами очередей

Ваша текущая конфигурация планирует queue:work каждую минуту, что может быть проблематично. По словам экспертов Laravel, воркеры очередей обычно не запускаются через планировщик:

Вы, вероятно, не захотите использовать планировщик для запуска воркеров очередей, так как они в конечном итоге являются разными вещами. Рассмотрите возможность использования supervisord для управления воркерами.
Ответ StackQueue о планировке воркеров очередей

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

Шаги по устранению неполадок

1. Проверьте, работает ли schedule:run вручную

Сначала убедитесь, что планировщик работает при ручном запуске:

bash
php artisan schedule:run

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

2. Очистите кэш приложения

Проблемы с кэшем могут препятствовать правильной работе планировщика:

bash
php artisan config:clear
php artisan cache:clear
php artisan route:clear

Если кто‑то сталкивался с этой проблемой в Laravel 10+, очистка кэша может помочь (это сработало для меня).
Ответ StackOverflow о очистке кэша в Laravel

3. Проверьте журналы ошибок

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

4. Проверьте права доступа к файлам

Убедитесь, что каталог storage/logs доступен для записи пользователем веб‑сервера.

Путеводитель по миграции

Чтобы исправить проблемы с планировкой в Laravel 12, необходимо перенести ваши запланированные задачи в новую структуру. Ниже приведены два подхода:

Вариант 1: Перенос в routes/console.php (рекомендовано)

  1. Создайте или отредактируйте файл routes/console.php
  2. Перенесите определение расписания из Kernel.php
  3. Удалите или измените файл Kernel.php
php
// routes/console.php
<?php

use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schedule;

// Ваши запланированные задачи
Schedule::command('queue:work --tries=3')
    ->runInBackground()
    ->withoutOverlapping()
    ->evenInMaintenanceMode()
    ->everyMinute();

if (app()->isProduction()) {
    Schedule::command('view:clear', ['--quiet'])
        ->withoutOverlapping()
        ->everyFiveMinutes();
}

Artisan::command('inspire', function () {
    $this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote');

Вариант 2: Использование bootstrap/app.php (альтернатива)

Для некоторых установок Laravel 12 может потребоваться переместить планировку в bootstrap/app.php:

php
// bootstrap/app.php
<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Support\Facades\Schedule;

$app = Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        // конфигурация middleware
    })
    ->withExceptions(function (Exceptions $exceptions) {
        // обработка исключений
    })
    ->create();

// Добавьте ваши запланированные задачи здесь
Schedule::command('queue:work --tries=3')
    ->runInBackground()
    ->withoutOverlapping()
    ->evenInMaintenanceMode()
    ->everyMinute();

if (app()->isProduction()) {
    Schedule::command('view:clear', ['--quiet'])
        ->withoutOverlapping()
        ->everyFiveMinutes();
}

return $app;

Исправление проблемы с воркером очередей

Вместо планирования queue:work рассмотрите возможность использования Supervisor для управления воркерами очередей:

  1. Установите Supervisor
  2. Создайте конфигурационный файл Supervisor
  3. Настройте его на непрерывный запуск php artisan queue:work --daemon

Этот подход более надёжен, чем запуск и остановка воркеров каждую минуту.


Вывод

  1. Основная проблема: Laravel 12 изменил способ определения запланированных задач – они больше не должны находиться в app/Console/Kernel.php, а перемещаются в routes/console.php или bootstrap/app.php.
  2. Проблема с воркером очередей: Планирование queue:work каждую минуту не оптимально – используйте Supervisor для непрерывной обработки очередей.
  3. Шаги миграции: Перенесите определения расписания в новое место, очистите кэши и проверьте права доступа.
  4. Проверка: Тестируйте с помощью php artisan schedule:run вручную и просматривайте журналы ошибок для отладки.
  5. Совместимость версий: Некоторые установки Laravel 12 могут всё ещё работать с Kernel.php, но другие требуют новой структуры – это неоднозначность, о которой сообщают пользователи.

Ключевой вывод: Laravel 12 привнес разрушающие изменения в систему планировщика, требующие адаптации кода, а не только конфигурации. Конфигурация cron корректна, но структура кода должна быть обновлена в соответствии с новыми конвенциями фреймворка.


Источники

  1. Документация по планировке задач Laravel 12.x
  2. Заметки к выпуску Laravel 11.x
  3. StackOverflow: Schedule in Laravel 11
  4. StackOverflow: Laravel Command Schedule Not Working
  5. StackOverflow: Laravel queue works only if started manually
Авторы
Проверено модерацией
Модерация