# Introduction
學習一個框架, Ray 的想法是, 在深入理解底層實作的原理之前, 應該先知道這個框架的 使用方法
; 先學習怎麼使用這個前人造的輪子, 再學習怎麼樣造一個輪子。
所以本篇文章重點在於細讀官方文件, 並將內容理解後以 Q&A 的方式記錄下來, 加速學習以及查詢。
# Defining Schedules
以下的 Laravel example code 的意思是?
- Example:
<?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
{
protected $commands = [
//
];
protected function schedule(Schedule $schedule)
{
$schedule->call(function () {
DB::table('recent_users')->delete();
})->daily();
}
} - Answer:
在App\Console\Kernel
class 的 schedule method 中定義 schedule, 在每天的晚上 12 點刪除 records in recent_users table
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(new DeleteRecentUsers)->daily(); - Answer:
除了 schedule closure, 也可以 schedule invokable object
以下的 Laravel example command 的意思是?
- Example:
<?php
php artisan schedule:list - Answer:
列出所有已定義的 schedule overview
# Scheduling Artisan Commands
以下的 Laravel example code 的意思是?
- Example:
<?php
use App\Console\Commands\SendEmailsCommand;
$schedule->command('emails:send Taylor --force')->daily();
$schedule->command(SendEmailsCommand::class, ['Taylor', '--force'])->daily(); - Answer:
使用 Laravel schedule 來 schedule command
以下的 Laravel example code 的意思是?
- Example:
<?php
use App\Jobs\Heartbeat;
$schedule->job(new Heartbeat, 'heartbeats', 'sqs')->everyFiveMinutes(); - Answer:
使用 Laravel schedule 來 schedule job, 並指定 queue 以及 connection
# Scheduling Shell Commands
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->exec('node /home/forge/script.js')->daily(); - Answer:
使用 Laravel schedule 來 schedule shell command
# Schedule Frequency Options
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->cron('* * * * *'); - Answer:
客製化的 cron schedule
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyMinute(); - Answer:
每分鐘執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyTwoMinutes(); - Answer:
每 2 分鐘執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyThreeMinutes(); - Answer:
每 3 分鐘執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyFourMinutes(); - Answer:
每 4 分鐘執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyFiveMinutes(); - Answer:
每 5 分鐘執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyTenMinutes(); - Answer:
每 10 分鐘執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyFifteenMinutes(); - Answer:
每 15 分鐘執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyThirtyMinutes(); - Answer:
每 30 分鐘執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->hourly(); - Answer:
每 1 小時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->hourlyAt(17); - Answer:
每 1 小時的 17 分執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyTwoHours(); - Answer:
每 2 小時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyThreeHours(); - Answer:
每 3 小時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everyFourHours(); - Answer:
每 4 小時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->everySixHours(); - Answer:
每 6 小時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->daily(); - Answer:
每 1 天 00:00 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->dailyAt('13:00'); - Answer:
每 1 天的 13:00 時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->twiceDaily(1, 13); - Answer:
每 1 天的 01:00 以及 13:00 時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->weekly(); - Answer:
每個 Sunday 00:00 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->weeklyOn(1, '8:00'); - Answer:
每個 Monday 8:00 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->monthly(); - Answer:
每個月的第一天 00:00 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->monthlyOn(4, '15:00'); - Answer:
每個月的第四天 15:00 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->twiceMonthly(1, 16, '13:00'); - Answer:
每個月的第一天, 第十六天 13:00 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->lastDayOfMonth('15:00'); - Answer:
每個月的最後一天, 15:00 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->quarterly(); - Answer:
每季的第一天 00:00 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->yearly(); - Answer:
每年的第一天 00:00 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->yearlyOn(6, 1, '17:00'); - Answer:
每年的六月一號 17:00 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->timezone('America/New_York'); - Answer:
定義 schedule timezone
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->weekly()->mondays()->at('13:00');
$schedule->command('foo')
->weekdays()
->hourly()
->timezone('America/Chicago')
->between('8:00', '17:00'); - Answer:
除了直接使用 constraint method, 也可以將不同的 constraint 連接起來
每個禮拜一的 13:00 執行
星期 1 - 5, 8:00 到 17:00 每小時執行一次
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->weekdays(); - Answer:
禮拜 1 - 5 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->weekends(); - Answer:
禮拜六 - 日 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->sundays(); - Answer:
禮拜日執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->mondays(); - Answer:
禮拜一執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->tuesdays; - Answer:
禮拜二執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->wednesdays; - Answer:
禮拜三執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->thursdays; - Answer:
禮拜四執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->fridays; - Answer:
禮拜五執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->saturdays(); - Answer:
禮拜六執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->days(array|mixed); - Answer:
在指定的 days 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->bewteen($startTime, $endTime); - Answer:
在指定的時間區間內執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->unlessBetween($startTime, $endTime); - Answer:
只在指定的時間區間內不執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->when(Closure); - Answer:
當 closure return true 時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->call(function () {
//
})->enviroments($env); - Answer:
若為指定的 env 時則執行, 例如 staging 或 production
# Day Constraints
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->hourly()
->days([0, 3]); - Answer:
在禮拜日, 禮拜三的每小時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
use Illuminate\Console\Scheduling\Schedule;
$schedule->command('emails:send')
->hourly()
->days([Schedule::SUNDAY, Schedule::WEDNESDAY]); - Answer:
在禮拜日, 禮拜三的每小時執行
# Between Time Constraints
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->hourly()
->between('7:00', '22:00'); - Answer:
在 7:00 到 22:00 之間, 每小時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->hourly()
->unlessBetween('23:00', '4:00'); - Answer:
在 23:00 到 04:00 之間不執行, 其餘時間每小時執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')->daily()->when(function () {
return true;
}); - Answer:
每天的 00:00, 若 when() 內 closure return true 執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')->daily()->skip(function () {
return true;
}); - Answer:
每天的 00:00, 若 skip() 內 closure return true 則不執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->daily()
->environments(['staging', 'production']); - Answer:
每天的 00:00, 若 env 為 staging 或 production 時執行
# Timezones
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('report:generate')
->timezone('America/New_York')
->at('2:00') - Answer:
New_York 時間的 2:00 執行
以下位於 App\Console\Kernel 的 Laravel example code 的意思是?
- Example:
<?php
protected function scheduleTimezone()
{
return 'America/Chicago';
} - Answer:
在 App\Console\Kernel 的 scheduleTimezone() 內可定義適用於 schedule 的 global timezone
Laravel 中, 為何不建議 timezone scheduling?
因為一些時區會使用夏令制, 也就是可能會多一個小時或少一個小時, 這會造成一個 schedule 在一天內執行兩次, 或完全不執行
# Preventing Task Overlaps
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')->withoutOverlapping(); - Answer:
使用 withoutOverlapping() 來避免 task 已經在執行中了, 又被執行
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')->withoutOverlapping(10); - Answer:
使用 withoutOverlapping() 來避免 task 已經在執行中了, 又被執行, 預設 withoutOverlapping lock 會在 24 hours 後失效, 也可帶入時間自定義, 單位為 minute
# Running Tasks On One Server
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('report:generate')
->fridays()
->at('17:00')
->onOneServer(); - Answer:
如果是跑多台 server 的話, scheduled task 很有可能會在多台 server 同時執行, 這樣就執行了多次, 浪費效能, 可使用 onOneServer(), 第一台取得該 scheduled task 執行權的 server 會給該 task 加上一個 lock, 避免重複執行
# Background Tasks
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('analytics:report')
->daily()
->runInBackground(); - Answer:
當使用 scheduled task 時, 預設會按照順序執行的, 如此一來, 如果遇到耗時較久的 task, 很有可能會造成阻塞, 這時可使用 runInBackground() 讓不同的 task 同時被執行, runInBackground() 只適用於 command 或 exec 的 scheduled task
# Maintenance Mode
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')->evenInMaintenanceMode(); - Answer:
預設在 maintenance mode 時, scheduled task 是不會被執行的, 如果依然想要執行的話, 可使用 evenInMaintenanceMode()
# Running The Scheduler
以下的 Laravel example code 的意思是?
- Example:
<?php
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1 - Answer:
schedule:run
指定會去判斷當下時間是否有需要執行任何已定義的 scheduled task, 所以必須使用 cron server, 每分鐘都執行一次schedule:run
# Running The Scheduler Locally
以下的 Laravel example code 的意思是?
- Example:
<?php
php artisan schedule:work - Answer:
在本地開發時, 我們不太會使用 cron 來跑 scheduled task, 這時可使用schedule:work
command 來暫時跑一個 process 在 foreground, 每分鐘都去執行schedule:run
# Task Output
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->daily()
->sendOutputTo($filePath); - Answer:
定義 scheduled task 的 output 位置, 會覆蓋該檔案
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->daily()
->appendOutputTo($filePath); - Answer:
定義 scheduled task 的 output append 位置, append 輸出
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('report:generate')
->daily()
->sendOutputTo($filePath)
->emailOutputTo('taylor@example.com'); - Answer:
定義 scheduled task 的 output 位置, 可定義機器內的檔案位置, 或是將 output 透過 email 發送
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('report:generate')
->daily()
->emailOutputOnFailure('taylor@example.com'); - Answer:
定義 scheduled task 的 output 透過 email 方式發送, 且只有在 non-zero exit code 時才發送
# Task Hooks
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->daily()
->before(function () {
// do something
})
->after(function () {
// do something
}); - Answer:
使用 before(), after(), 在 scheduled task 被執行前以及執行後執行一些邏輯
以下的 Laravel example code 的意思是?
- Example:
<?php
use Illuminate\Support\Stringable;
$schedule->command('emails:send')
->daily()
->onSuccess(function (Stringable $output) {
// do something
})
->onFailure(function (Stringable $output) {
// do something
}); - Answer:
使用 onSuccess(), onFailure(), 在 scheduled task 執行成功或失敗後做一些事, 並且可使用 type hint Stringable 來存取 output
# Pinging URLs
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->daily()
->pingBefore($url)
->thenPing($url); - Answer:
使用 pingBefore(), thenPing(), 在 scheduled task 執行前後 ping 指定的 url
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->daily()
->pingBeforeIf($condition, $url)
->thenPingIf($condition, $url); - Answer:
ping arg2 的 $url, 如果 arg1 $condition 為 true 的話
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->daily()
->pingOnSuccess($successUrl)
->pingOnFailure($failureUrl); - Answer:
會在 success 時 ping $successUrl, fails 時 ping $failureUrl
以下的 Laravel example code 的意思是?
- Example:
<?php
$schedule->command('emails:send')
->twiceDailyAt(1, 13, 5); - Answer:
一天跑兩次, 分別在 01:05, 以及 13:05 時執行
留言