Aufgabenplanung in Laravel

PHPz
Freigeben: 2023-09-01 09:06:01
Original
1496 Leute haben es durchsucht

Aufgabenplanung in Laravel

In diesem Artikel stellen wir eine spannende Funktion des Laravel-Webframeworks vor – die Aufgabenplanung. Wir schauen uns an, wie Sie mit Laravel geplante Aufgaben in Ihrer Anwendung verwalten können. Darüber hinaus werden wir irgendwann zu Demonstrationszwecken unsere eigene benutzerdefinierte geplante Aufgabe erstellen.

Mit dem Laravel-Framework können Sie geplante Aufgaben einrichten, sodass Sie sich nicht um deren Einrichtung auf Systemebene kümmern müssen. Sie können beim Einrichten geplanter Aufgaben auf die komplexe Cron-Syntax verzichten, da Sie diese mit Laravel benutzerfreundlich definieren können.

Wir besprechen zunächst, wie man einen herkömmlichen Cron-Job einrichtet, und erkunden dann, wie Laravel ihn implementiert. In der zweiten Hälfte dieses Artikels werden wir es ausprobieren, indem wir ein paar benutzerdefinierte geplante Aufgaben erstellen, die praktische Einblicke in das Thema geben sollen.

Traditionelle Einstellungen für geplante Aufgaben

In der täglichen Anwendungsentwicklung müssen Sie häufig bestimmte Skripte oder Befehle regelmäßig ausführen. Wenn Sie ein *nix-System verwenden, wissen Sie wahrscheinlich, dass Cron-Jobs diese Befehle verarbeiten. Auf Windows-basierten Systemen werden sie hingegen als geplante Aufgaben bezeichnet.

Werfen wir einen kurzen Blick auf ein einfaches Beispiel eines *nix-basierten Cron-Jobs.

*/5 * * * * /web/statistics.sh
Nach dem Login kopieren

Ganz einfach – die Datei statistics.sh wird alle fünf Minuten ausgeführt!

Obwohl dies ein sehr einfaches Beispiel ist, müssen Sie häufig komplexere Anwendungsfälle implementieren. Komplexe Systeme erfordern die Definition mehrerer Cron-Jobs, die in unterschiedlichen Abständen ausgeführt werden.

Sehen wir uns einige der Aufgaben an, die komplexe Webanwendungen regelmäßig im Backend ausführen müssen.

  • Bereinigen Sie unnötige Daten im Datenbank-Backend.
  • Aktualisieren Sie den Frontend-Cache-Index, um auf dem neuesten Stand zu bleiben.
  • Berechnen Sie Website-Statistiken.
  • Senden Sie eine E-Mail.
  • Sichern Sie verschiedene Website-Elemente.
  • Berichte erstellen.
  • Da ist noch mehr.

Wie Sie sehen, warten viele Dinge darauf, regelmäßig und in unterschiedlichen Abständen ausgeführt zu werden. Wenn Sie ein erfahrener Systemadministrator sind, können Sie für all diese Aufgaben problemlos Cron-Jobs definieren, aber manchmal wünschen wir uns als Entwickler einen einfacheren Weg.

Glücklicherweise verfügt Laravel über eine integrierte Aufgabenplanungs-API, mit der Sie geplante Aufgaben wie nie zuvor definieren können. Ja, im nächsten Abschnitt geht es um die Grundlagen der Laravel-Aufgabenplanung.

Der Laravel-Weg

Im vorherigen Abschnitt haben wir die traditionelle Methode zum Einrichten eines Cronjobs behandelt. In diesem Abschnitt stellen wir Laravel im Kontext der Aufgabenplanungs-API ausführlich vor.

Bevor wir fortfahren, ist es wichtig zu verstehen, dass die von Laravel bereitgestellte Planungsfunktion wie jede andere Funktionalität ist und nicht automatisch aufgerufen wird. Wenn Sie also denken, dass Sie auf Systemebene nichts tun müssen, dann würde ich sagen, dass Sie Pech haben.

Wenn Sie das Laravel-Planungssystem verwenden möchten, sollten Sie als Erstes einen Cron-Job einrichten, der jede Minute ausgeführt wird, und den im folgenden Codeausschnitt gezeigten artisan-Befehl aufrufen.

* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1
Nach dem Login kopieren

Der obige artisan-Befehl ruft den Laravel-Scheduler auf, der dann alle in der Anwendung definierten ausstehenden Cron-Jobs ausführt.

Natürlich haben wir noch nicht gesehen, wie man geplante Aufgaben in einer Laravel-Anwendung definiert, was wir als nächstes ausführlich besprechen werden.

Dies ist die AppConsoleKernel 类的 schedule Methode, die Sie verwenden müssen, wenn Sie anwendungsspezifische geplante Aufgaben definieren möchten.

Fahren Sie fort, um den Inhalt der Datei app/Console/Kernel.php abzurufen.

<?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 = [
        //
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')->hourly();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}
Nach dem Login kopieren

Wie Sie sehen können, ist der Kerncode selbst ein nützliches Beispiel. Im obigen Beispiel führt Laravel stündlich den Befehl inspire inspire artisan aus. Finden Sie nicht, dass die Syntax von vornherein intuitiv ist?

Tatsächlich ermöglicht Ihnen Laravel, geplante Aufgaben auf viele verschiedene Arten zu definieren:

  • Verwenden Sie Abschlüsse/Callables.
  • Rufen Sie den artisan-Befehl auf.
  • Shell-Befehle ausführen.

Außerdem stehen unzählige integrierte Planungsfrequenzen zur Auswahl:

  • Jede Minute/alle fünf Minuten
  • Stündlich/Täglich/Wöchentlich/Vierteljährlich/Jährlich
  • Bestimmte Tageszeiten
  • Es gibt noch mehr

Tatsächlich würde ich sagen, dass es einen vollständigen Satz an Routinen bietet, sodass Sie benutzerdefinierte Cron-Jobs erstellen können, ohne die Shell zu berühren!

Ja, ich kann sehen, dass Sie sich fragen, wie Sie Ihre benutzerdefinierten geplanten Aufgaben umsetzen können, was ich am Anfang des Artikels versprochen habe.

Erstellen Sie Ihre erste geplante Aufgabe in Laravel

Wie bereits erwähnt, können Sie mit Laravel geplante Aufgaben auf unterschiedliche Weise definieren. Mal sehen, wie es nacheinander funktioniert.

Abschluss-/Aufrufbare Methode

Die Scheduling-API stellt die call-Methode bereit, mit der Sie eine aufrufbare Funktion oder Abschlussfunktion ausführen können. Ändern wir die Datei app/Console/Kernel.php mit dem folgenden Code.

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\DB;

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)
    {
        // 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();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}
Nach dem Login kopieren

如您所见,我们将闭包函数作为 call 方法的第一个参数传递。另外,我们将频率设置为每 30 分钟一次,因此它将每 30 分钟执行一次关闭函数!

在我们的示例中,我们计算每个用户的帖子总数并相应地更新 statistics 表。

artisan 命令

除了闭包或可调用之外,您还可以安排一个 artisan 命令,该命令将按一定的时间间隔执行。事实上,它应该是优于闭包的首选方法,因为它同时提供了更好的代码组织和可重用性。

继续使用以下内容修改 app/Console/Kernel.php 文件的内容。

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use Illuminate\Support\Facades\DB;

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)
    {
        $schedule->command('statistics:user')->everyThirtyMinutes();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}
Nach dem Login kopieren

这是 command 方法,如果您希望安排 artisan 命令,如上面的代码片段所示,您可以使用该方法。您需要传递 artisan 命令签名作为 command 方法的第一个参数。

当然,你还需要在app/Console/Commands/UserStatistics.php处定义相应的artisan命令。

<?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]);
    }
  }
}
Nach dem Login kopieren

exec 命令

我们可以说到目前为止我们讨论的方法是特定于 Laravel 应用程序本身的。此外,Laravel 还允许您安排 shell 命令,以便您也可以运行外部应用程序。

让我们通过一个简单的示例来演示如何每天备份数据库。

<?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');
  }
}
Nach dem Login kopieren

从代码中可以明显看出,您需要使用调度程序的 exec 方法,并且需要将要运行的命令作为其第一个参数传递。

除此之外,我们还使用了 sendOutputTo 方法,它允许您收集命令的输出。另一方面,有一个方法,emailOutputTo,它允许您通过电子邮件发送输出内容!

如何防止任务重叠

在本节中,我们将了解如何防止任务重叠。假设您已经定义了一个任务,并且您想要确保如果它已经在运行,Laravel 不应该运行同一任务的另一个实例。默认情况下,Laravel 将始终开始运行计划任务,即使同一任务的前一个实例已经在运行但尚未完成。

那么让我们看看如何避免重叠计划任务。

$schedule->command('statistics:user')->everyThirtyMinutes()->withoutOverlapping();
Nach dem Login kopieren

正如你所看到的,你只需要使用 withoutOverlapping 方法来确保 Laravel 不会与已经运行的任务重叠。默认情况下,Laravel 重叠任务之前的锁定时间为 24 小时。如果您想覆盖它,可以按照以下代码片段所示进行操作。

$schedule->command('statistics:user')->everyThirtyMinutes()->withoutOverlapping(30);
Nach dem Login kopieren

在上面的示例中,Laravel 等待 30 分钟才清除重叠锁。

如何定义后台任务

如果您同时安排多个任务,Laravel 会按顺序运行它们。因此,如果您有一个需要很长时间才能执行的任务,则下一个计划任务将不得不等待很长时间。为了避免这种情况,您可以在后台执行此类任务。

让我们快速看一下下面的示例,了解如何定义后台任务。

$schedule->command('statistics:user')->daily()->runInBackground();
Nach dem Login kopieren

如您所见,您可以使用 runInBackground 方法来定义后台任务。

结论

今天,我们了解了 Laravel Web 框架中的任务调度 API。看到它如何轻松地管理需要定期运行的任务真是令人着迷。

在文章的开头,我们讨论了传统的设置计划任务的方式,接下来我们介绍了 Laravel 的设置方式。在本文的后半部分,我们通过几个实际示例来演示任务调度概念。

我希望您喜欢这篇文章,并且您应该对在 Laravel 中设置计划任务更有信心。对于那些刚刚开始使用 Laravel 或希望通过扩展来扩展您的知识、网站或应用程序的人,我们在 Envato Market 上提供了多种您可以学习的内容。

Das obige ist der detaillierte Inhalt vonAufgabenplanung in Laravel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage