Планировщик задач
Очистить старые записи ночью, раз в час обновить курсы валют, по понедельникам отправить отчёт — такие задачи выполняются по расписанию. Обычно для каждой добавляют строку в cron на сервере. В Laravel расписание описано в коде проекта, а на сервере нужна всего одна запись.
Расписание
Задачи описывают в файле routes/console.php:
use Illuminate\Support\Facades\Schedule;
Schedule::command('reports:send')->weeklyOn(1, '9:00');
Schedule::command('model:prune')->daily();Первая строка запускает команду Artisan по понедельникам в девять утра, вторая — каждый день в полночь.
Что можно запланировать
use App\Jobs\UpdateExchangeRates;
use Illuminate\Support\Facades\DB;
Schedule::job(new UpdateExchangeRates)->hourly();
Schedule::call(function () {
DB::table('sessions')->where('last_activity', '<', now()->subWeek()->timestamp)->delete();
})->daily();
Schedule::exec('node /var/www/scripts/report.js')->monthly();job() отправляет задание в очередь, call() выполняет функцию, exec() — команду операционной системы.
Частота
| Метод | Когда выполняется |
|---|---|
everyMinute() | Каждую минуту |
everyFiveMinutes() | Каждые пять минут |
hourly() | В начале каждого часа |
daily() | Каждый день в полночь |
dailyAt('13:00') | Каждый день в указанное время |
weekly() | Раз в неделю |
monthly() | Первого числа каждого месяца |
cron('0 */6 * * *') | По выражению cron |
Ограничения
Schedule::command('emails:send')
->weekdays()
->between('8:00', '18:00')
->timezone('Europe/Moscow');
Schedule::command('backup:run')
->daily()
->environments(['production']);Защита от наложения
Если задача выполняется дольше, чем интервал между запусками, следующий запуск начнётся поверх предыдущего. withoutOverlapping() этого не допускает:
Schedule::command('import:products')
->everyFiveMinutes()
->withoutOverlapping();На сайте с несколькими серверами добавляют onOneServer(), чтобы задача выполнилась только на одном.
Запуск на сервере
В cron сервера добавляют единственную строку. Она каждую минуту вызывает планировщик, а тот сам решает, что пора выполнить:
* * * * * cd /var/www/blog && php artisan schedule:run >> /dev/null 2>&1Проверка
php artisan schedule:list
php artisan schedule:workПервая команда показывает все задачи и время следующего запуска. Вторая запускает планировщик в терминале — так расписание проверяют при разработке, без настройки cron.
Частая ошибка
Время в расписании считается в часовом поясе приложения — по умолчанию это UTC. Задача dailyAt('9:00') выполнится в девять утра по Гринвичу, то есть в полдень по Москве. Укажите пояс в настройке timezone файла config/app.php или методом timezone() у самой задачи.