タスクスケジューリングとは
従来、サーバーで定期実行が必要なタスクごとに cron エントリを手書きする必要がありました。 しかしこの方法ではスケジュール定義がソースコード外に存在するため、バージョン管理できず、確認・変更のたびに SSH ログインが必要になります。 Laravelのスケジューラを使うと、アプリケーション内でスケジュールを流暢に定義できます。 サーバーに登録する cron エントリは1行だけで済み、スケジュール定義はコードとともにバージョン管理されます。 スケジュールはroutes/console.php に定義するのが標準的なスタイルです。
schedule:list Artisanコマンドで、定義済みのタスク一覧と次回実行予定時刻を確認できます。スケジューラーの実行フロー
スケジュールの定義方法
スケジュールの定義はroutes/console.php に記述します。
bootstrap/app.php の withSchedule メソッドを使って定義する方法もあります。
スケジュール可能なタスクの種類
Artisanコマンドのスケジュール
command メソッドでArtisanコマンドをスケジュールします。
コマンド名またはクラス名で指定できます。
キュージョブのスケジュール
job メソッドでキュージョブをスケジュールします。
クロージャを使わずにジョブをキューに積む便利な方法です。
シェルコマンドのスケジュール
exec メソッドでOSコマンドを実行します。
クロージャのスケジュール
call メソッドで任意のPHPクロージャをスケジュールします。
__invoke メソッドを持つ Invocable オブジェクトも渡せます。
スケジュール頻度の設定
主な頻度メソッド
よく使う頻度メソッドを以下に示します。cron式で直接指定
cron メソッドで cron 式を直接指定することもできます。
頻度と曜日の組み合わせ
頻度メソッドと曜日の制約を組み合わせて、より細かいスケジュールを作れます。タイムゾーンの設定
timezone メソッドで個別タスクのタイムゾーンを指定できます。
config/app.php の schedule_timezone を使います。
条件制約
when / skip
when はクロージャが true を返した場合のみタスクを実行します。
skip はその逆で、true を返した場合にスキップします。
environments
environments メソッドで特定の環境でのみ実行するよう制限できます。
時刻の制約
between / unlessBetween で実行時間帯を制限できます。
曜日の制約
重複防止
デフォルトでは、前回のタスクがまだ実行中でも次の実行が開始されます。withoutOverlapping を使うと、前の実行が終わるまで次の実行を待機させられます。
withoutOverlapping はアプリケーションのキャッシュを使ってロックを管理します。
タスクが予期せぬ問題でスタックした場合は schedule:clear-cache でロックを解除できます。複数サーバーでの実行制御
複数サーバーでスケジューラが動いている場合、onOneServer を使うことで1台のサーバーだけでタスクを実行できます。
onOneServer() による分散実行制御フロー
タスクのグループ化
複数のタスクに同じ設定を適用する場合はgroup メソッドを使ってまとめられます。
バックグラウンド実行
同じ時刻にスケジュールされたタスクは、デフォルトでは定義順に順番に実行されます。 長時間かかるタスクがあると後続のタスクの開始が遅れます。runInBackground を使うと、タスクをバックグラウンドで並列実行できます。
メンテナンスモード
アプリケーションがメンテナンスモードのとき、スケジュールタスクは実行されません。 メンテナンスモード中でも強制的に実行させたい場合はevenInMaintenanceMode を使います。
メンテナンスモードの対応フロー
スケジューラの一時停止
コードを変更せずにスケジューラを一時停止できます。evenWhenPaused を使います。
ヘルスチェックやシステム監視など、メンテナンス中でも継続が必要なタスクに役立ちます。
出力のハンドリング
ファイルへの出力
sendOutputTo でタスクの出力をファイルに保存できます。
appendOutputTo を使うと、既存のファイルに追記します。
メールへの出力
emailOutputTo でタスクの出力をメールで送信できます。
事前にLaravelのメール設定が必要です。
emailOutputOnFailure を使います。
タスクフック
before / after メソッドで、タスクの実行前後に処理を挿入できます。
onSuccess / onFailure で定義します。
サーバーへのデプロイ
1
cron エントリを追加する
サーバーの crontab に以下の1行を追加するだけで、Laravelのスケジューラが毎分実行されます。
crontab -e コマンドで編集できます。2
スケジューラの動作を確認する
定義済みタスクの一覧と次回実行時刻を確認します。
ローカル開発での実行
ローカル環境では cron を使わず、schedule:work コマンドでスケジューラを常時起動できます。
Ctrl+C で停止するまで動き続けます。
サブ分スケジュール(1分未満の頻度)
通常の cron は1分が最小単位ですが、Laravelでは1秒単位のスケジュールも設定できます。schedule:run はその分が終わるまで動き続けて、すべてのサブ分タスクを処理します。
デプロイ中に実行中の schedule:run を中断するには、デプロイスクリプトに以下を追加します。