Laravel (5.7) Планирование задач
Настройка традиционных запланированных задач
При повседневной разработке приложений вы часто сталкиваетесь с ситуацией, когда вам необходимо периодически выполнять определенные сценарии или команды. Если вы работаете с системой * nix, вы, вероятно, знаете, что задания cron обрабатывают эти команды. С другой стороны, они известны как запланированные задачи в системах на базе Windows.
Давайте кратко рассмотрим простой пример работы cron на основе * nix.
1 */5 * * * * /web/statistics.sh
Довольно просто - он запускает файл statistics.sh каждые пять минут!
Хотя это был довольно простой вариант использования, вы часто оказывались в ситуации, которая требует от вас реализации более сложных вариантов использования. С другой стороны, сложная система требует, чтобы вы определили несколько заданий cron, которые выполняются в разные промежутки времени.
Давайте посмотрим на некоторые задачи, которые сложные веб-приложения должны периодически выполнять в серверной части.
- Очистите ненужные данные от базы данных.
- Обновите внешние индексы кэширования, чтобы поддерживать их актуальность.
- Рассчитать статистику сайта.
- Отправлять электронную почту.
- Резервное копирование различных элементов сайта.
- Генерация отчетов.
- И больше.
Итак, как вы можете видеть, есть много вещей, ожидающих запуска периодически и в разные промежутки времени. Если вы опытный системный администратор, вы можете легко определить задания cron для всех этих задач, но иногда мы, как разработчики, желаем, чтобы был более простой путь.
К счастью, Laravel поставляется со встроенным API планирования задач, который позволяет вам определять запланированные задачи, как никогда раньше.
И да, в следующем разделе все об этом - основы планирования задач Laravel.
Путь Ларавела
В предыдущем разделе мы рассмотрели традиционный способ создания заданий cron. В этом разделе мы рассмотрим особенности Laravel в контексте API планирования задач.
Прежде чем мы продолжим, важно понять, что функция планирования, предоставляемая Laravel, похожа на любую другую функцию и не будет вызываться автоматически. Так что если вы думаете, что вам не нужно ничего делать на системном уровне, то вам не повезло, я бы сказал.
Фактически, первое, что вы должны сделать, если хотите использовать систему планирования Laravel, - это настроить задание cron, которое будет запускаться каждую минуту и вызывать команду ремесленника, показанную в следующем фрагменте.
1 * * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
Вышеприведенная команда ремесленников вызывает планировщик Laravel, который, в свою очередь, выполняет все ожидающие задания cron, определенные в вашем приложении.
Конечно, нам еще предстоит выяснить, как определить запланированные задачи в вашем приложении Laravel, и это следующая вещь, в которую мы углубимся.
Это метод расписания класса AppConsoleKernel, который вам нужно использовать, если вы хотите определить специфичные для приложения запланированные задачи.
Продолжайте и возьмите содержимое файла app / Console / Kernel.php.
<?php namespace App\Console;
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 = [
'App\Console\Commands\Inspire',
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('inspire')->hourly();
}
}
Как видите, сам код ядра предоставляет полезный пример. В приведенном выше примере Laravel ежечасно выполняет команду вдохновляющего ремесленника. Вам не кажется, что синтаксис настолько интуитивно понятен?
Фактически, есть несколько различных способов, которыми Laravel позволяет вам определять задачи расписания:
- Используйте закрытие / вызываемый.
- Позвоните в ремесленное командование.
- Выполните команду оболочки.
Кроме того, существует множество встроенных частот планирования, которые вы можете выбрать:
- каждую минуту / каждые пять минут
- ежечасно / ежедневно / еженедельно / ежеквартально / ежегодно
- в определенное время суток
- и многое другое
На самом деле, я бы сказал, что он предоставляет полный набор процедур, так что вам никогда не нужно прикасаться к оболочке для создания ваших пользовательских заданий cron!
Да, я могу сказать, что вам не терпится узнать, как реализовать свои собственные запланированные задачи, и это то, что я также обещал в начале статьи.
Создайте свою первую запланированную задачу в Laravel
Как мы уже говорили, существуют разные способы, с помощью которых Laravel позволяет вам определять запланированные задачи. Давайте пройдемся по каждому, чтобы понять, как это работает.
Закрытие / вызываемый метод
API планирования обеспечивает метод вызова, который позволяет вам выполнять вызываемую или закрывающую функцию. Давайте изменим файл app / Console / Kernel.php с помощью следующего кода.
<?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
{
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// the call method
$schedule->call(function () {
$posts = DB::table('posts')
->select('user_id', DB::raw('count(*) as total_posts'))
->groupBy('user_id')
->get();
foreach($posts as $post)
{
DB::table('users_statistics')
->where('user_id', $post->user_id)
->update(['total_posts' => $post->total_posts]);
}
})->everyThirtyMinutes();
}
}
Как видите, мы передали функцию замыкания в качестве первого аргумента метода вызова. Кроме того, мы установили частоту каждые 30 минут, поэтому она будет выполнять функцию закрытия каждые 30 минут!
В нашем примере мы подсчитываем общее количество сообщений на пользователя и соответственно обновляем таблицу статистики.
Ремесленное командование
Помимо замыканий или вызовов, вы также можете запланировать ремесленную команду, которая будет выполняться через определенные промежутки времени. Фактически, это должен быть предпочтительный подход по сравнению с замыканиями, поскольку он обеспечивает лучшую организацию кода и возможность многократного использования.
Продолжите и измените содержимое файла app / Console / Kernel.php следующим образом.
<?php
namespace App\Console;
use Illuminate\Support\Facades\Config;
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 = [
'App\Console\Commands\UserStatistics'
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// artisan command method
$schedule->command('statistics:user')->everyThirtyMinutes();
}
/**
* Register the Closure based commands for the application.
*
* @return void
*/
protected function commands()
{
require base_path('routes/console.php');
}
}
Это командный метод, который вы хотели бы использовать, если вы хотите запланировать команду ремесленника, как показано в приведенном выше фрагменте кода. Вам необходимо передать подпись команды ремесленника в качестве первого аргумента метода команды.
Конечно, вам также необходимо определить соответствующую команду ремесленника в app / Console / Commands / UserStatistics.php.
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class UserStatistics extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature ='statistics:user';
/**
* The console command description.
*
* @var string
*/
protected $description ='Update user statistics';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
// calculate new statistics
$posts = DB::table('posts')
->select('user_id', DB::raw('count(*) as total_posts'))
->groupBy('user_id')
->get();
// update statistics table
foreach($posts as $post)
{
DB::table('users_statistics')
->where('user_id', $post->user_id)
->update(['total_posts' => $post->total_posts]);
}
}
}
Exec Command
Можно сказать, что методы, которые мы обсуждали до сих пор, были специфичны для самого приложения Laravel. Кроме того, Laravel также позволяет планировать команды оболочки, чтобы вы могли запускать и внешние приложения.
Давайте рассмотрим быстрый пример, который демонстрирует, как делать резервную копию вашей базы данных каждый день.
<?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.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// exec method
$host = config('database.connections.mysql.host');
$username = config('database.connections.mysql.username');
$password = config('database.connections.mysql.password');
$database = config('database.connections.mysql.database');
$schedule->exec("mysqldump -h {$host} -u {$username} -p{$password} {$database}")
->daily()
->sendOutputTo('/backups/daily_backup.sql');
}
}
Из кода видно, что вам нужно использовать метод exec планировщика, и вам нужно передать команду, которую вы хотели бы запустить, в качестве первого аргумента.
Кроме того, мы также использовали метод sendOutputTo, который позволяет вам собирать выходные данные команды. С другой стороны, есть метод emailOutputTo, который позволяет отправлять выводимое содержимое по электронной почте!
Предыдущая: Laravel (5.7) Очереди
Далее: Учебник Laravel (5.7) Базы данных
Новый контент: Composer: менеджер зависимостей для PHP , R программирования