Вступление
Раньше вы могли создавать записи Cron для каждой задачи, которую вам нужно было запланировать на вашем сервере. Однако, это может быстро стать проблемой, потому что ваше расписание задач больше не находится под контролем исходного кода, и вы должны подключиться к серверу по SSH, чтобы добавить дополнительные записи Cron.
Планировщик команд Laravel позволяет вам свободно и выразительно определять расписание команд в самом Laravel. При использовании планировщика на вашем сервере требуется только одна запись Cron. Расписание вашей задачи определяется в методе файла . Чтобы помочь вам начать, в методе определен простой пример.app/Console/Kernel.php
schedule
Запуск планировщика
При использовании планировщика вам нужно всего лишь добавить следующую запись Cron на ваш сервер. Если вы не знаете, как добавить записи Cron на ваш сервер, рассмотрите возможность использования службы, такой как Laravel Forge, которая может управлять записями Cron для вас:
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
Этот Cron будет вызывать планировщик команд Laravel каждую минуту. Когда команда будет выполнена, Laravel оценит ваши запланированные задачи и выполнит задачи, которые должны быть выполнены.schedule:run
Определение расписаний
Вы можете определить все свои запланированные задачи в schedule
методе класса. Для начала давайте рассмотрим пример планирования задачи. В этом примере мы планируем вызывать a каждый день в полночь. Внутри мы выполним запрос к базе данных, чтобы очистить таблицу:App\Console\Kernel
Closure
Closure
<?php
namespace App\Console;
use Illuminate\Support\Facades\DB;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
DB::table('recent_users')->delete();
})->daily();
}
}
Помимо планирования с помощью замыканий, вы также можете использовать вызываемые объекты . Вызываемые объекты - это простые классы PHP, которые содержат __invoke
метод:
$schedule->call(new DeleteRecentUsers)->daily();
Планирование команд ремесленников
Помимо планирования вызовов Closure, вы также можете запланировать команды Artisan и команды операционной системы. Например, вы можете использовать command
метод для планирования команды Artisan, используя либо имя команды, либо класс:
$schedule->command('emails:send Taylor --force')->daily();
$schedule->command(EmailsCommand::class, ['Taylor', '--force'])->daily();
Планирование заданий в очереди
Этот job
метод может использоваться для планирования работы в очереди . Этот метод обеспечивает удобный способ планирования заданий без использования call
метода для создания замыканий вручную для постановки в очередь:
$schedule->job(new Heartbeat)->everyFiveMinutes();
// Dispatch the job to the "heartbeats" queue...
$schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes();
Планирование команд оболочки
Этот exec
метод может использоваться для выдачи команды операционной системе:
$schedule->exec('node /home/forge/script.js')->daily();
Варианты частоты расписания
Существует множество расписаний, которые вы можете назначить для своей задачи:
метод | Описание |
---|---|
->cron('* * * * *'); |
Запустите задачу по индивидуальному расписанию Cron. |
->everyMinute(); |
Запускать задание каждую минуту |
->everyFiveMinutes(); |
Запускать задание каждые пять минут |
->everyTenMinutes(); |
Выполняйте задание каждые десять минут |
->everyFifteenMinutes(); |
Запускать задание каждые пятнадцать минут |
->everyThirtyMinutes(); |
Выполняйте задание каждые тридцать минут |
->hourly(); |
Запускать задание каждый час |
->hourlyAt(17); |
Запускать задание каждый час в 17 минут после часа |
->daily(); |
Выполняйте задание каждый день в полночь |
->dailyAt('13:00'); |
Запускать задание каждый день в 13:00 |
->twiceDaily(1, 13); |
Выполняйте задание ежедневно в 1:00 и 13:00 |
->weekly(); |
Запускать задание каждую неделю |
->weeklyOn(1, '8:00'); |
Выполняйте задание каждую неделю в понедельник в 8:00. |
->monthly(); |
Запускать задание каждый месяц |
->monthlyOn(4, '15:00'); |
Выполняйте задание каждый месяц 4го числа в 15:00. |
->quarterly(); |
Выполняйте задание каждую четверть |
->yearly(); |
Запускать задачу каждый год |
->timezone('America/New_York'); |
Установите часовой пояс |
Эти методы могут быть объединены с дополнительными ограничениями для создания даже более точно настроенных расписаний, которые выполняются только в определенные дни недели. Например, чтобы запланировать выполнение команды еженедельно в понедельник:
// Run once per week on Monday at 1 PM...
$schedule->call(function () {
//
})->weekly()->mondays()->at('13:00');
// Run hourly from 8 AM to 5 PM on weekdays...
$schedule->command('foo')
->weekdays()
->hourly()
->timezone('America/Chicago')
->between('8:00', '17:00');
Ниже приведен список дополнительных ограничений графика:
метод | Описание |
---|---|
->weekdays(); |
Ограничить задачу днями |
->weekends(); |
Ограничьте задачу выходными |
->sundays(); |
Ограничить задачу до воскресенья |
->mondays(); |
Ограничить задачу понедельником |
->tuesdays(); |
Ограничить задачу вторником |
->wednesdays(); |
Ограничить задачу до среды |
->thursdays(); |
Ограничить задачу четвергом |
->fridays(); |
Ограничить задачу пятницей |
->saturdays(); |
Ограничить задачу субботой |
->between($start, $end); |
Ограничить выполнение задачи между временем начала и окончания |
->when(Closure); |
Ограничить задачу на основе теста на правду |
->environments($env); |
Ограничить задачу конкретными средами |
Между временными ограничениями
Этот between
метод может использоваться для ограничения выполнения задачи в зависимости от времени суток:
$schedule->command('reminders:send')
->hourly()
->between('7:00', '22:00');
Точно так же unlessBetween
метод может использоваться, чтобы исключить выполнение задачи на период времени:
$schedule->command('reminders:send')
->hourly()
->unlessBetween('23:00', '4:00');
Ограничения теста правды
Этот when
метод может использоваться для ограничения выполнения задачи на основе результата данного теста истинности. Другими словами, если заданное значение Closure
возвращается true
, задача будет выполняться до тех пор, пока никакие другие ограничивающие условия не препятствуют ее выполнению:
$schedule->command('emails:send')->daily()->when(function () {
return true;
});
skip
Метод может рассматриваться как обратное when
. Если skip
метод возвращается true
, запланированное задание не будет выполнено:
$schedule->command('emails:send')->daily()->skip(function () {
return true;
});
При использовании цепных when
методов запланированная команда будет выполняться только в случае when
возврата всех условий true
.
Ограничения окружающей среды
environments
Метод может быть использован для выполнения задач только на заданных условиях:
$schedule->command('emails:send')
->daily()
->environments(['staging', 'production']);
Часовые пояса
Используя timezone
метод, вы можете указать, что время запланированной задачи должно интерпретироваться в пределах данного часового пояса:
$schedule->command('report:generate')
->timezone('America/New_York')
->at('02:00')
Если вы назначаете один и тот же часовой пояс всем запланированным задачам, вы можете определить scheduleTimezone
метод в своем файле. Этот метод должен возвращать часовой пояс по умолчанию, который должен быть назначен всем запланированным задачам:app/Console/Kernel.php
/**
* Get the timezone that should be used by default for scheduled events.
*
* @return \DateTimeZone|string|null
*/
protected function scheduleTimezone()
{
return 'America/Chicago';
}
Помните, что некоторые часовые пояса используют летнее время. Когда происходят изменения летнего времени, запланированное задание может выполняться дважды или даже не запускаться вообще. По этой причине мы рекомендуем избегать планирования часовых поясов, когда это возможно.
Предотвращение дублирования задач
По умолчанию запланированные задачи будут выполняться, даже если предыдущий экземпляр задачи все еще выполняется. Чтобы предотвратить это, вы можете использовать withoutOverlapping
метод:
$schedule->command('emails:send')->withoutOverlapping();
В этом примере команда Artisan будет выполняться каждую минуту, если она еще не запущена. Этот метод особенно полезен, если у вас есть задачи, которые сильно различаются по времени выполнения, что не позволяет вам точно предсказать, сколько времени займет выполнение данной задачи.emails:send
withoutOverlapping
При необходимости вы можете указать, сколько минут должно пройти, пока не истечет блокировка «без наложения». По умолчанию срок действия блокировки истекает через 24 часа:
$schedule->command('emails:send')->withoutOverlapping(10);
Выполнение задач на одном сервере
Чтобы использовать эту функцию, ваше приложение должно использовать драйвер кэширования
memcached
или вredis
качестве драйвера кэша вашего приложения по умолчанию. Кроме того, все серверы должны взаимодействовать с одним и тем же сервером центрального кэша.
Если ваше приложение работает на нескольких серверах, вы можете ограничить выполнение запланированного задания только на одном сервере. Например, предположим, что у вас есть запланированное задание, которое генерирует новый отчет каждую пятницу вечером. Если планировщик заданий работает на трех рабочих серверах, запланированное задание будет выполнено на всех трех серверах и сгенерирует отчет три раза. Нехорошо!
Чтобы указать, что задача должна выполняться только на одном сервере, используйте onOneServer
метод при определении запланированной задачи. Первый сервер, получивший задачу, обеспечит атомарную блокировку для задания, чтобы другие серверы не могли одновременно выполнить ту же задачу:
$schedule->command('report:generate')
->fridays()
->at('17:00')
->onOneServer();
Фоновые задачи
По умолчанию несколько команд, запланированных одновременно, будут выполняться последовательно. Если у вас есть длительные команды, это может привести к тому, что последующие команды начнутся намного позже, чем ожидалось. Если вы хотите запускать команды в фоновом режиме, чтобы все они могли выполняться одновременно, вы можете использовать runInBackground
метод:
$schedule->command('analytics:report')
->daily()
->runInBackground();
Режим технического обслуживания
Запланированные задачи Laravel не будут выполняться, когда Laravel находится в режиме обслуживания , поскольку мы не хотим, чтобы ваши задачи мешали выполнению незаконченного обслуживания, которое вы можете выполнять на своем сервере. Однако, если вы хотите, чтобы задача выполнялась даже в режиме обслуживания, вы можете использовать evenInMaintenanceMode
метод:
$schedule->command('emails:send')->evenInMaintenanceMode();
Вывод задачи
Планировщик Laravel предоставляет несколько удобных методов для работы с выводом, генерируемым запланированными задачами. Сначала, используя sendOutputTo
метод, вы можете отправить вывод в файл для последующей проверки:
$schedule->command('emails:send')
->daily()
->sendOutputTo($filePath);
Если вы хотите добавить вывод к данному файлу, вы можете использовать appendOutputTo
метод:
$schedule->command('emails:send')
->daily()
->appendOutputTo($filePath);
Используя этот emailOutputTo
метод, вы можете отправить результаты на электронный адрес по вашему выбору. Перед отправкой по электронной почте вывода задачи, вы должны настроить почтовые службы Laravel :
$schedule->command('foo')
->daily()
->sendOutputTo($filePath)
->emailOutputTo('foo@example.com');
Если вы хотите отправить вывод по электронной почте только в случае сбоя команды, используйте emailOnFailure
метод:
$schedule->command('foo')
->daily()
->emailOnFailure('foo@example.com');
В
emailOutputTo
,emailOnFailure
,sendOutputTo
иappendOutputTo
методы являются исключительными кcommand
иexec
методам.
Крюки задач
Использование before
и after
методы, вы можете задать код , который будет выполняться до и после того , как запланированное задание завершено:
$schedule->command('emails:send')
->daily()
->before(function () {
// Task is about to start...
})
->after(function () {
// Task is complete...
});
В onSuccess
и onFailure
методы позволяют задать код , который будет выполняться , если запланированное задание успешно или не:
$schedule->command('emails:send')
->daily()
->onSuccess(function () {
// The task succeeded...
})
->onFailure(function () {
// The task failed...
});
Проверка связи с URL
Используя pingBefore
и thenPing
методы, планировщик может автоматически пинговать заданный URL до или после того, как задача будет завершена. Этот метод полезен для уведомления внешней службы, такой как Laravel Envoyer , о том, что ваша запланированная задача начинается или закончила выполнение:
$schedule->command('emails:send')
->daily()
->pingBefore($url)
->thenPing($url);
Эти pingBeforeIf
и thenPingIf
методы могут использоваться для проверки заданного URL , только если данное условие true
:
$schedule->command('emails:send')
->daily()
->pingBeforeIf($condition, $url)
->thenPingIf($condition, $url);
Эти pingOnSuccess
и pingOnFailure
методы могут использоваться для проверки заданного URL только если задача успешно или не:
$schedule->command('emails:send')
->daily()
->pingOnSuccess($successUrl)
->pingOnFailure($failureUrl);
Все методы ping требуют HTTP-библиотеки Guzzle. Вы можете добавить Guzzle в свой проект, используя менеджер пакетов Composer:
composer require guzzlehttp/guzzle
0 комментариев