什麼是任務排程
過去在伺服器上要定期執行的任務,每個都需手動撰寫 cron entry。 但這樣的排程定義存在於原始碼之外,無法納入版本控制,每次確認或變更都需要 SSH 登入。 使用 Laravel 的排程器,可在應用程式內流暢定義排程。 在伺服器上只需登記一行 cron entry,排程定義隨程式碼一起納入版控。 排程通常寫在routes/console.php,是標準風格。
用
schedule:list Artisan 指令可查看已定義任務清單與下次執行時間。排程器的執行流程
排程的定義方式
排程定義寫在routes/console.php。
也可以透過 bootstrap/app.php 的 withSchedule 方法定義。
可排程的任務種類
Artisan 指令的排程
用command 方法排程 Artisan 指令。
可用指令名稱或類別名稱指定。
Queue Job 的排程
用job 方法排程queue job。
是不用 closure 就能把 job 送入 queue 的便利方法。
Shell 指令的排程
用exec 方法執行 OS 指令。
Closure 的排程
用call 方法排程任意 PHP closure。
__invoke 方法的 Invocable 物件。
設定排程頻率
主要頻率方法
以下為常用的頻率方法。用 cron 式直接指定
也可用cron 方法直接指定 cron 式。
頻率與星期的組合
結合頻率方法與星期限制可製作更精細的排程。設定時區
用timezone 方法可為個別任務指定時區。
config/app.php 的 schedule_timezone。
條件限制
when / skip
when 在 closure 回傳 true 時執行任務。
skip 相反,回傳 true 時跳過。
environments
用environments 方法可限制只在特定環境執行。
時間的限制
用between / unlessBetween 可限制執行時段。
星期的限制
防止重複
預設情況下,即使上次的任務仍在執行也會啟動下次執行。 用withoutOverlapping 可讓下一次執行等待上次結束。
withoutOverlapping 使用應用程式的快取管理鎖定。
任務因非預期問題卡住時,可用 schedule:clear-cache 解除鎖定。多台伺服器的執行控制
若多台伺服器都執行排程器,可用onOneServer 讓任務只在一台伺服器執行。
onOneServer() 的分散執行控制流程
任務分組
當多個任務要套用相同設定時,可用group 方法整合。
背景執行
同時刻排程的任務預設會依定義順序依序執行。 若有長時間任務,會延遲後續任務的開始。 用runInBackground 可讓任務在背景平行執行。
維護模式
當應用程式處於維護模式時,排程任務不會執行。 若要在維護模式中仍強制執行,使用evenInMaintenanceMode。
維護模式的處理流程
暫停排程器
可在不改動程式碼下暫停排程器。evenWhenPaused。
適用於健康檢查或系統監控等即使維護中也需持續執行的任務。
輸出處理
輸出到檔案
用sendOutputTo 可將任務輸出存入檔案。
appendOutputTo 則會附加到既有檔案。
輸出到郵件
用emailOutputTo 可將任務輸出以郵件寄送。
需先完成 Laravel 的郵件設定。
emailOutputOnFailure。
任務 Hook
以before / after 方法可在任務執行前後插入處理。
onSuccess / onFailure 定義。
部署到伺服器
1
加入 cron entry
在伺服器的 crontab 加入以下一行,Laravel 排程器就會每分鐘執行。可用
crontab -e 指令編輯。2
確認排程器運作
確認已定義任務清單與下次執行時間。
本機開發時的執行
本機可不用 cron,而是用schedule:work 指令常駐排程器。
Ctrl+C 停止前會持續運作。
Sub-minute 排程(小於 1 分的頻率)
一般 cron 最小單位為 1 分鐘,但 Laravel 可設定以秒為單位的排程。schedule:run 會持續運行到該分鐘結束以處理所有 sub-minute 任務。
若要在部署期間中斷執行中的 schedule:run,在部署腳本加入以下: