Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас

Розклад Laravel у cron

Який cron-вираз стоїть за everyFifteenMinutes()

Дані не залишають ваш браузер

Цей інструмент повністю працює на вашому пристрої: обчислення виконує JavaScript у вкладці. Ми не надсилаємо введений текст на сервер, не зберігаємо і не логуємо його. Можете сміливо працювати з робочими даними - і навіть відключити інтернет після завантаження сторінки.

Метод планувальника Cron-вираз
everyMinute() * * * * *
everyTwoMinutes() */2 * * * *
everyFiveMinutes() */5 * * * *
everyTenMinutes() */10 * * * *
everyFifteenMinutes() */15 * * * *
everyThirtyMinutes() */30 * * * *
hourly() 0 * * * *
everyTwoHours() 0 */2 * * *
everySixHours() 0 */6 * * *
daily() 0 0 * * *
twiceDaily() 0 1,13 * * *
weekly() 0 0 * * 0
monthly() 0 0 1 * *
quarterly() 0 0 1 1-12/3 *
yearly() 0 0 1 1 *
weekdays() * * * * 1-5
weekends() * * * * 6,0
mondays() * * * * 1
sundays() * * * * 0
Рядок для crontab
* * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1

У crontab потрібен рівно один запис - той, що запускає планувальник щохвилини. Далі Laravel сам вирішує, чия задача має виконатися.

Поділитись

Що це показує

Планувальник Laravel описує розклад методами - dailyAt('03:00'), everyFifteenMinutes(), weeklyOn(1, '09:00'). Кожен із них під капотом просто встановлює cron-вираз.

Знати який - корисно у трьох випадках: коли треба пояснити розклад людині поза проєктом, коли задачу переносять у зовнішній планувальник (Kubernetes CronJob, GitHub Actions), і коли поведінка задачі не збігається з очікуванням.

Зворотний напрям - розібрати готовий вираз і побачити найближчі запуски - робить валідатор cron.

Таблиця вище звірена з самим Laravel: тест проходить кожен метод через справжній Schedule і порівнює вираз. Саме ця перевірка й виявила, що everyThirtyMinutes() встановлює */30 * * * *, а не 0,30 * * * *, як здається інтуїтивно.

Один запис у crontab

Найважливіше про планувальник Laravel: у системному crontab потрібен рівно один рядок, а не по одному на задачу.

* * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1

Cron щохвилини запускає schedule:run, а той уже сам вирішує, чия задача має виконатися саме зараз. Тому додати нову задачу - це змінити PHP-файл, а не чіпати crontab на сервері.

У Docker цей рядок часто замінює окремий контейнер із supervisord або schedule:work, який робить те саме в циклі:

php artisan schedule:work

Чотири методи, які варто додавати майже завжди

Schedule::command('report:heavy')
    ->dailyAt('03:00')
    ->withoutOverlapping()
    ->onOneServer()
    ->runInBackground()
    ->timezone('Europe/Kyiv');

withoutOverlapping() - запобіжник від класичної аварії: важка задача не встигає за інтервал, запуски накопичуються один на одного і кладуть сервер. За замовчуванням блокування тримається годину; для довгих задач передавайте своє значення.

onOneServer() обов'язковий, якщо серверів кілька: без нього щоденний звіт розсилається стільки разів, скільки у вас інстансів. Потребує спільного кешу - Redis або memcached.

runInBackground() не дає одній довгій задачі затримати весь розклад: без нього наступні задачі чекають, поки ця завершиться.

timezone() важливий саме в Україні. Перехід на літній час зсуває «щоденну о 9:00», якщо пояс не заданий явно, - а задача, прив'язана до 02:30, у день переходу може або не виконатися, або виконатися двічі.

Перевірка розкладу

php artisan schedule:list    # що і коли запуститься
php artisan schedule:run     # виконати те, що припадає на зараз
php artisan schedule:test    # запустити конкретну задачу вручну

schedule:list показує наступний час виконання для кожної задачі - найшвидший спосіб переконатися, що розклад означає те, що ви думали.

Коли краще черга, а не розклад

Планувальник відповідає на питання «коли», черга - на питання «не в цьому запиті». Якщо задача важка, її місце в черзі, навіть коли запускає її розклад:

// Розклад лише кладе задачу в чергу, а не виконує її сам
Schedule::call(fn () => GenerateMonthlyReport::dispatch())->monthlyOn(1, '03:00');

Так падіння задачі не залишить schedule:run висіти, а повторні спроби візьме на себе черга.