>  기사  >  백엔드 개발  >  Laravel의 작업 스케줄링

Laravel의 작업 스케줄링

PHPz
PHPz원래의
2023-09-01 09:05:061466검색

Laravel의 작업 스케줄링

이 기사에서는 Laravel 웹 프레임워크의 흥미로운 기능인 작업 스케줄링을 소개합니다. Laravel을 사용하여 애플리케이션에서 예약된 작업을 관리하는 방법을 살펴보겠습니다. 또한 최종적으로 데모 목적으로 자체 사용자 정의 예약 작업을 생성할 것입니다.

Laravel 프레임워크를 사용하면 예약된 작업을 설정할 수 있으므로 시스템 수준에서 설정하는 것에 대해 걱정할 필요가 없습니다. Laravel을 사용하면 사용자 친화적인 방식으로 작업을 정의할 수 있으므로 예약된 작업을 설정할 때 복잡한 cron 구문에서 벗어날 수 있습니다.

먼저 전통적인 cron 작업을 설정하는 방법을 다룬 다음 Laravel이 이를 구현하는 방식을 살펴보겠습니다. 이 문서의 후반부에서는 주제에 대한 실질적인 통찰력을 제공하는 몇 가지 사용자 지정 예약 작업을 만들어 시도해 보겠습니다.

기존 예약 작업 설정

일상적인 애플리케이션 개발에서는 특정 스크립트나 명령을 정기적으로 실행해야 하는 경우가 많습니다. *nix 시스템을 사용한다면 cron 작업이 이러한 명령을 처리한다는 것을 알고 있을 것입니다. 반면, Windows 기반 시스템에서는 예약된 작업이라고 합니다.

*nix 기반 크론 작업의 간단한 예를 간단히 살펴보겠습니다.

으아아아

매우 간단합니다. 5분마다 statistics.sh 파일을 실행합니다!

이것은 매우 간단한 예이지만 더 복잡한 사용 사례를 구현해야 하는 경우가 많습니다. 복잡한 시스템에서는 서로 다른 간격으로 실행되는 여러 cron 작업을 정의해야 합니다.

복잡한 웹 애플리케이션이 백엔드에서 정기적으로 수행해야 하는 몇 가지 작업을 살펴보겠습니다.

  • 데이터베이스 백엔드에서 불필요한 데이터를 정리합니다.
  • 프런트엔드 캐시 색인을 업데이트하여 최신 상태를 유지하세요.
  • 웹사이트 통계를 계산합니다.
  • 이메일을 보내세요.
  • 다양한 웹사이트 요소를 백업하세요.
  • 보고서를 생성합니다.
  • 더 있습니다.

보시다시피, 정기적으로, 그리고 다양한 간격으로 실행되기를 기다리는 것들이 많이 있습니다. 숙련된 시스템 관리자라면 이러한 모든 작업에 대해 cron 작업을 쉽게 정의할 수 있지만 개발자로서 더 쉬운 방법을 원하는 경우도 있습니다.

다행히도 Laravel에는 이전과는 전혀 다른 방식으로 예약된 작업을 정의할 수 있는 작업 예약 API가 내장되어 있습니다. 예, 다음 섹션은 Laravel 작업 스케줄링의 기본 사항에 관한 것입니다.

라라벨 방식

이전 섹션에서는 크론 작업을 설정하는 전통적인 방법을 다루었습니다. 이번 섹션에서는 작업 스케줄링 API의 맥락에서 Laravel을 자세히 소개하겠습니다.

계속하기 전에 이해해야 할 중요한 점은 Laravel에서 제공하는 스케줄링 기능은 다른 기능과 동일하며 자동으로 호출되지 않는다는 것입니다. 따라서 시스템 수준에서 아무것도 할 필요가 없다고 생각한다면 운이 없다고 말하고 싶습니다.

실제로 Laravel 스케줄링 시스템을 사용하려면 가장 먼저 해야 할 일은 매분 실행되는 cron 작업을 설정하고 다음 코드 조각에 표시된 artisan 명령을 호출하는 것입니다.

으아아아

위의 artisan 명령은 Laravel 스케줄러를 호출한 다음 애플리케이션에 정의된 보류 중인 모든 크론 작업을 실행합니다.

물론, 우리는 Laravel 애플리케이션에서 예약된 작업을 정의하는 방법을 보지 못했습니다. 이에 대해서는 다음에 자세히 논의하겠습니다.

이것은 애플리케이션별 예약된 작업을 정의하려는 경우 사용해야 하는 AppConsoleKernel 类的 schedule 방법입니다.

계속해서 app/Console/Kernel.php 파일의 콘텐츠를 가져옵니다.

으아아아

보시다시피 핵심 코드 자체가 유용한 예를 제공합니다. 위의 예에서 Laravel은 inspire inspire artisan 명령을 매시간 실행합니다. 처음부터 구문이 직관적이라고 생각하지 않나요?

사실 Laravel을 사용하면 예약된 작업을 다양한 방법으로 정의할 수 있습니다:

  • 클로저/콜러블을 사용하세요.
  • artisan 명령을 호출하세요.
  • 쉘 명령을 실행합니다.

또한 다음 중에서 선택할 수 있는 일정 빈도가 내장되어 있습니다.

  • 매분/5분마다
  • 시간별/일별/주별/분기별/연간
  • 특정 시간대
  • 더 있습니다

사실, 완전한 루틴 세트를 제공하므로 셸을 건드리지 않고도 사용자 정의 크론 작업을 만들 수 있습니다!

예, 기사 시작 부분에서 약속한 대로 사용자 정의 예약 작업을 구현하는 방법을 궁금해하시는 것으로 보입니다.

Laravel에서 첫 번째 예약된 작업을 생성하세요

우리가 논의한 것처럼 Laravel을 사용하면 예약된 작업을 다양한 방식으로 정의할 수 있습니다. 어떻게 작동하는지 하나씩 살펴보겠습니다.

클로저/호출 가능 메서드

Scheduling API는 호출 가능한 함수나 클로저 함수를 실행할 수 있는 call 메서드를 제공합니다. 다음 코드를 사용하여 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 = [
        //
    ];

    /**
     * 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');
    }
}

如您所见,我们将闭包函数作为 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');
    }
}

这是 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]);
    }
  }
}

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');
  }
}

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

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

如何防止任务重叠

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

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

$schedule->command('statistics:user')->everyThirtyMinutes()->withoutOverlapping();

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

$schedule->command('statistics:user')->everyThirtyMinutes()->withoutOverlapping(30);

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

如何定义后台任务

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

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

$schedule->command('statistics:user')->daily()->runInBackground();

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

结论

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

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

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

위 내용은 Laravel의 작업 스케줄링의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:PHP FTP다음 기사:PHP FTP