Laravel入坑指南(番外)——任務調度

Laravel提供了很是強勁的命令行工具(若是還不瞭解,傳送到第8往篇),咱們若是想要按期執行某個命令行,能夠利用crontab進行定時設置。若是有多個按期的任務,很簡單,咱們設定多條crontab規則在不一樣時間段內調度不一樣的命令便可。php

而Laravel框架內部也提供了這樣的調度機制。(固然,仍是逃不過crontab的支持)html

 

首先,咱們須要在crontab中添加這麼一條規則node

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

 

 

其次,全部的調度任務都在/app/Console/Kernel.php的schedule函數中進行調度設置redis

 

 

這個函數中能夠調度閉包、可調用對象(包含__invoke的對象)、artisian命令、列隊任務以及shell命令。如下以例子進行說明:shell

//調度閉包,->daily()即調度選項,天天凌晨零點運行任務
//關於調度選項後面會統一說明
$schedule->call(function () {
    DB::table('recent_users')->delete();
})->daily();


//調度可調用對象
//DeleteRecentUsers類中包含了__invoke魔術方法
$schedule->call(new DeleteRecentUsers)->daily();


//調度artisian命令
$schedule->command('emails:send --force')->daily();
$schedule->command(EmailsCommand::class, ['--force'])->daily();


//調度列隊任務
$schedule->job(new Heartbeat)->everyFiveMinutes();
$schedule->job(new Heartbeat, 'heartbeats')->everyFiveMinutes();    //將job投遞到heartbeats列隊中


//調度shell命令
$schedule->exec('node /home/forge/script.js')->daily();

經常使用的調度選項:編程

方法 描述
->cron('* * * * *'); 在自定義Cron調度上運行任務
->everyMinute(); 每分鐘運行一次任務
->everyFiveMinutes(); 每五分鐘運行一次任務
->everyTenMinutes(); 每十分鐘運行一次任務
->everyFifteenMinutes(); 每十五分鐘運行一次任務
->everyThirtyMinutes(); 每三十分鐘運行一次任務
->hourly(); 每小時運行一次任務
->hourlyAt(17); 每小時第十七分鐘運行一次任務
->daily(); 天天凌晨零點運行任務
->dailyAt('13:00'); 天天13:00運行任務
->twiceDaily(1, 13); 天天1:00 & 13:00運行任務
->weekly(); 每週運行一次任務
->monthly(); 每個月運行一次任務
->monthlyOn(4, '15:00'); 每個月4號15:00運行一次任務
->quarterly(); 每一個季度運行一次
->yearly(); 每一年運行一次
->timezone('America/New_York'); 設置時區

 

額外調度約束選項:閉包

方法 描述
->weekdays(); 只在工做日運行任務
->weekends(); 只在週末運行任務
->sundays(); 每一個星期天運行任務
->mondays(); 每一個星期一運行任務
->tuesdays(); 每一個星期二運行任務
->wednesdays(); 每一個星期三運行任務
->thursdays(); 每一個星期四運行任務
->fridays(); 每一個星期五運行任務
->saturdays(); 每一個星期六運行任務
->between($start, $end); 基於特定時間段運行任務
->when(Closure); 基於特定測試運行任務
->environments($env); 只在指定環境運行任務

 

舉幾個例子:app

// 每週星期一13:00運行一次...
$schedule->call(function () {
    
})->weekly()->mondays()->at('13:00');


// 工做日的上午8點到下午5點每小時運行...
$schedule->command('foo')
         ->weekdays()
         ->hourly()
         ->timezone('America/Chicago')
         ->between('8:00', '17:00');


//天天7點到22點之間,每小時運行
$schedule->command('reminders:send')
         ->hourly()
         ->between('7:00', '22:00');


//天天23點到4點以外的時間內,每小時運行
$schedule->command('reminders:send')
         ->hourly()
         ->unlessBetween('23:00', '4:00');


//when的閉包返回true時運行
$schedule->command('emails:send')->daily()->when(function () {
    return true;
});


//skip的閉包返回false時運行
$schedule->command('emails:send')->daily()->skip(function () {
    return true;
});

 

 

第三,任務調度的重疊處理框架

當下一次任務開始執行時,萬一上一次的任務尚未執行完成,新的任務是會執行的。也就是說,有可能出現屢次任務重疊執行的狀況。less

爲了不這種狀況,咱們可使用外部的手段來加鎖,好比文件鎖flock,或者redis的setnx均可以。可是Laravel很是貼心,已經幫咱們準備了這樣的機制:

$schedule->command('emails:send')->withoutOverlapping();    //鎖默認24小時失效

$schedule->command('emails:send')->withoutOverlapping(10);    //鎖10分鐘失效

 

 

第四,任務調度的順序

默認狀況下,同時調度的多個命令會順序執行。若是你有一些長時間運行的命令,將會致使隨後的命令在預期以後好久才能執行。若是你想要讓命令在後臺執行以便它們能夠同時運,可使用 runInBackground 方法來實現:

$schedule->command('analytics:report')
     ->daily()
     ->runInBackground();

 

 

第五,任務輸出

咱們能夠將任務中的輸出重定向覆蓋寫入或追加寫入文件中,便於問題的排查:

//覆蓋寫入
$schedule->command('emails:send')
     ->daily()
     ->sendOutputTo($filePath);

//追加寫入
$schedule->command('emails:send')
     ->daily()
     ->appendOutputTo($filePath);

 

 

最後,任務鉤子

使用 before 和 after 方法,你能夠指定在調度任務完成以前和以後要執行的代碼:

$schedule->command('emails:send')
         ->daily()
         ->before(function () {
             // 任務即將開始...
         })
         ->after(function () {
             // 任務已經完成...
         });

 

 

好了,Laravel話題到這裏正式結束了。關於Laravel還有一些知識點,若是想要深刻了解的小夥伴就去看官方文檔吧。

下週開始,博主會進入另外一個話題。至於要寫什麼,嗯,還沒想好,你們下週再見:)

 

 

---------------------------  我是可愛的分割線  ----------------------------

最後博主借地宣傳一下,漳州編程小組招新了,這是一個面向漳州青少年信息學/軟件設計的學習小組,有意向的同窗點擊連接,聯繫我吧。

相關文章
相關標籤/搜索