Статьи

Планирование задач в Laravel

В этой статье мы рассмотрим одну из замечательных функций веб-фреймворка Laravel — планирование задач. В этой статье мы рассмотрим, как Laravel позволяет вам управлять запланированными задачами в вашем приложении. Кроме того, мы также создадим наши собственные запланированные задачи для демонстрационных целей.

Инфраструктура Laravel позволяет вам настраивать запланированные задачи, чтобы вам не приходилось беспокоиться об их настройке на системном уровне. Вы можете избавиться от этого сложного синтаксиса cron при настройке запланированных задач, поскольку Laravel позволяет вам определять их удобным для пользователя способом.

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

При повседневной разработке приложений вы часто сталкиваетесь с ситуацией, когда вам необходимо периодически выполнять определенные сценарии или команды. Если вы работаете с системой * 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, и это следующая вещь, в которую мы углубимся.

Это метод schedule класса App\Console\Kernel который вам нужно использовать, если вы хотите определить специфичные для приложения запланированные задачи.

Продолжайте и возьмите содержимое файла app/Console/Kernel.php .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?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 ежечасно выполняет команду inspire ремесленника. Вам не кажется, что синтаксис настолько интуитивно понятен?

На самом деле, есть несколько разных способов, с помощью которых Laravel позволяет вам определять задачи по расписанию:

  • Используйте закрытие / вызываемый.
  • Позвоните в ремесленное командование.
  • Выполните команду оболочки.

Кроме того, есть много встроенных частот планирования, которые вы можете выбрать:

  • каждую минуту / каждые пять минут
  • ежечасно / ежедневно / еженедельно / ежеквартально / ежегодно
  • в определенное время суток
  • и многое другое

На самом деле, я бы сказал, что он предоставляет полный набор процедур, так что вам никогда не нужно прикасаться к оболочке для создания ваших пользовательских заданий cron!

Да, я могу сказать, что вам не терпится узнать, как реализовать свои собственные запланированные задачи, и это то, что я также обещал в начале статьи.

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

API планирования обеспечивает метод call который позволяет вам выполнять вызываемую функцию или функцию закрытия. Давайте app/Console/Kernel.php файл app/Console/Kernel.php с помощью следующего кода.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?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();
  }
}

Как видите, мы передали функцию закрытия в качестве первого аргумента метода call . Кроме того, мы установили частоту каждые 30 минут, поэтому она будет выполнять функцию закрытия каждые 30 минут!

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

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

app/Console/Kernel.php и измените содержимое файла app/Console/Kernel.php следующим образом.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?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’);
  }
}

Это command метод, который вы хотели бы использовать, если вы хотите запланировать команду ремесленника, как показано в приведенном выше фрагменте кода. Вам нужно передать подпись команды ремесленника в качестве первого аргумента метода command .

Конечно, вам нужно определить соответствующую команду ремесленника также в app/Console/Commands/UserStatistics.php .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?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]);
    }
  }
}

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

Давайте рассмотрим быстрый пример, который демонстрирует, как делать резервную копию вашей базы данных каждый день.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?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 , который позволяет emailOutputTo по электронной почте!

И это подводит нас к концу статьи. Фактически, мы только что поцарапали поверхность API планирования Laravel, и в его наборе есть что предложить.

Сегодня мы рассмотрели API планирования задач в веб-фреймворке Laravel. Было интересно увидеть, насколько легко он позволяет вам управлять задачами, которые нужно периодически запускать.

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

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

Если что-то всплывет у вас в голове, давайте начнем разговор, используя канал ниже!