剖析 Laravel 計劃任務--初探

Ryan發表於2017-07-12

譯文GitHub https://github.com/yuansir/diving-laravel-zh

原文連結 https://divinglaravel.com/task-scheduling/before-the-dive

想象這種情況,作為一個大型SaaS的開發者,您需要找到一種在週末每分鐘選擇10個隨機客戶的方式,並提供折扣升級,傳送折扣的工作可能非常簡單,但我們需要每分鐘執行一次,為此我分享一些CRON的簡要介紹給還不熟悉人。

CRON是一個守護程式,它駐留在你的linux伺服器中,大部分時間都沒有喚醒,但是每一分鐘它都會睜開雙眼,看看是否執行任何給定的任務,你使用crontab檔案與該守護程式通訊,在大多數常見的設定檔案可以位於/etc/crontab,crontab檔案可能看起來像這樣:

0 0 1 * * /home/full-backup
0 0 * * * /home/partial-backup
30 5 10 * * /home/check-subscriptions

在crontab檔案中,每行表示一個計劃任務作業,每個作業定義包含兩部分:

  1. *****部分代表該作業執行的計時器。
  2. 第二部分是應執行的命令

CRON時序語法

5個星號按順序排列如下:

  1. 一小時內的分鐘
  2. 一天內的小時
  3. 一個月內的日期
  4. 一年內的月份
  5. 一週的內的天

示例:

  • 0 0 1 * * 在第一個例子中,表示該工作應在每月,每個月的第一個天,上午12點,每小時第一分鐘執行。 或者簡單地說,它應該在每月的第一天上午12:00執行。
  • 0 * * * * 在第二個例子中,表示該工作應該每小時執行一次。
  • 30 5 10 * * 表示該工作應該在每個月10日上午5:30執行

這裡還有一些其他的示例:

  • * * * * 3 表示工作應該在星期三每分鐘執行一次。
  • * * * * 1-5 表示該工作應該每週一至週五執行。
  • 0 1,15 * * * 表示該工作應該每天在凌晨1點和3點執行兩次。
  • */10 * * * * 表示該工作應該每10分鐘執行一次。

所以我們為我們的工作註冊一個cron任務?

是的,我們可以在我們的crontab檔案中註冊:

 * * * * php /home/divingLaravel/artisan send:offer

該命令將通知CRON守護程式每分鐘執行 php artisan send:offer artisan命令,是不是很容易? 但是,當我們想要在星期四和星期二或每個特定日子裡每分鐘執行命令時會感到困惑,記住cron作業的語法不是一件容易的事,而且還需要更新crontab檔案,你想新增一個新的工作或更新的時間表可能是相當耗時的時間,所以幾個版本釋出後Laravel新增了一些有趣的功能,為排程任務提供了一個容易記住的語法:

$schedule->command('send:offer')
          ->everyFiveMinutes()
          ->wednesdays();

你只需要在你的crontab中註冊一個cron工作,laravel會處理剩下的事:

* * * * * php /divingLaravel/artisan schedule:run >> /dev/null 2>&1

您可以在App\Console\Kernel類的schedule方法中定義預定的命令:

protected function schedule(Schedule $schedule)
{
    $schedule->command('send:offer')
          ->everyFiveMinutes()
          ->wednesdays();
}

如果您想了解有關不同計時器選項的更多資訊,請檢視 官方文件

當Console Kernel被例項化時,Laravel向核心的booted事件註冊一個偵聽器,該事件將Scheduler繫結到容器並呼叫kernel的schedule()方法:

// in Illuminate\Foundation\Console\Kernel

public function __construct(Application $app, Dispatcher $events)
{
    $this->app->booted(function () {
        $this->defineConsoleSchedule();
    });
}

protected function defineConsoleSchedule()
{
     // Register the Scheduler in the Container
    $this->app->instance(
        Schedule::class, $schedule = new Schedule($this->app[Cache::class])
    );

     // Call the schedule() method that we override in our App\Console\Kernel
    $this->schedule($schedule);
}

一旦console kernel完成Kernel類中定義的引導順序,這個booted事件就被觸發。

在Kernel的handle()方法中,Laravel會檢查Foundation\Application是否已啟動,如果不是呼叫應用程式的bootstrapWith()方法,並傳遞在console Kernel定義的載入程式陣列。

簡單地說:

當CRON守護程式每分鐘都呼叫php artisan schedule:run命令時,控制檯Console Kernel將被啟動,您在App\Console\Kernel::schedule()方法中定義的作業將被註冊到排程程式。

schedule()方法呼叫Illuminate\Console\Scheduling\Schedule的例項作為唯一的引數,這是用於記錄您提供的作業的計劃工作管理員,並決定每次CRON守護程式應該執行什麼。

轉載請註明: 轉載自Ryan是菜鳥 | LNMP技術棧筆記

如果覺得本篇文章對您十分有益,何不 打賞一下

謝謝打賞

本文連結地址: 剖析Laravel計劃任務--初探

相關文章