キューとは
Webアプリケーションでは、メール送信・画像のリサイズ・外部APIへの問い合わせなど、完了まで数秒かかる処理が発生することがあります。 これをHTTPリクエストの中で同期的に行うと、ユーザーはレスポンスが返るまで待ち続けなければなりません。 Laravelのキューを使うと、こうした重い処理をバックグラウンドで非同期に実行できます。 リクエストはすぐにレスポンスを返し、実際の処理はワーカープロセスが別途こなしてくれます。キューはデータベース・Redis・Amazon SQSなど複数のバックエンドに対応しています。
開発環境では
sync ドライバを使うと、キューを使わずジョブを即時実行できます。キューの設定
config/queue.php
キューの設定はconfig/queue.php に集約されています。
QUEUE_CONNECTION 環境変数で使用するドライバを切り替えます。
.env の設定
データベースドライバの準備
database ドライバを使う場合、ジョブを保存するテーブルが必要です。
Laravel 11以降の新規プロジェクトには最初からマイグレーションが含まれていますが、
含まれていない場合は次のコマンドで作成します。
Redisドライバの準備
redis ドライバを使う場合は config/database.php にRedis接続設定を追加し、
Composerでドライバをインストールします。
SQS Overflow Storage
Amazon SQS はメッセージペイロードの最大サイズに制限があります。 ペイロードが大きくなるジョブを扱う場合は、超過分をキャッシュストアに保存し、SQSにはポインターのみを送る設定を追加します。enabledを有効にすると、1MB以上のペイロードを指定したキャッシュストアへ保存します。alwaysをtrueにすると、サイズに関係なくすべてのSQSペイロードをキャッシュストアに保存します。delete_after_processingはジョブ成功後に保存済みペイロードを削除します(デフォルトtrue)。flush_on_clearをtrueにするとqueue:clear実行時にoverflow用ストアをflushします。通常のキャッシュを消さないため、専用ストアと組み合わせて使ってください。
ジョブクラスの作成
make:job コマンド
make:job Artisanコマンドでジョブクラスのひな型を生成します。
app/Jobs/SendWelcomeEmail.php が生成されます。
ジョブクラスの構造
ShouldQueue インターフェースを実装することで、このジョブがキューで非同期処理されることをLaravelに伝えます。
Queueable トレイトがジョブのキュー操作に必要なメソッドを提供します。
ジョブのディスパッチ
dispatch()
コントローラやサービスからジョブをキューに送り出すにはdispatch() を使います。
遅延ディスパッチ
delay() メソッドでジョブの実行を指定時間後に遅らせられます。
dispatchAfterResponse()
dispatchAfterResponse() を使うと、HTTPレスポンスをユーザーに返した直後にジョブを実行します。
sync ドライバでも動作するため、専用のワーカーが不要な軽量な用途に向いています。
特定のキューへのディスパッチ
Queue Routing
特定のジョブクラスをデフォルトで決まった接続・キューに振り向けるには、ServiceProviderのboot() で Queue::route() を使います。ジョブクラスごとに onQueue() / onConnection() を書く代わりに一元管理できます。
Queue Routing はジョブ側の
onQueue() / onConnection() で上書きできます。同期実行(テスト・開発用)
dispatchSync() を使うと、キューを経由せずに即時実行します。
バルクディスパッチ
多数の独立したジョブを一度にディスパッチする場合、Bus ファサードの bulk() メソッドを使用できます。バッチ処理のような追跡やコールバックが不要なケースに最適です。
Bus::bulk() は、ジョブを設定されたキュー接続とキュー名でグループ化し、各グループをまとめてキューにプッシュするため効率的です。
Bus::bulk() はジョブをバッチとしてまとめてキューに送信します。バッチ処理(Bus::batch())とは異なり、進捗追跡や完了コールバックは提供されません。独立した大量のジョブをシンプルに一括送信したい場合に適しています。ジョブの処理
queue:work コマンド
キューワーカーを起動してジョブを処理します。キューワーカーの監視オプション
よく使うオプションを組み合わせてワーカーを細かく制御できます。ジョブクラスにリトライ設定を書く
コマンドラインオプションより、ジョブクラス自体に設定を書く方が管理しやすい場合があります。ジョブのリリース(Release ミドルウェア)
特定の条件を満たすときにジョブを実行せずキューに戻したい場合、Release ミドルウェアを使うと簡潔に書けます。
Release::unless() は条件が false のときにリリースします。
失敗したジョブの処理
failed_jobs テーブルの準備
ジョブが最大試行回数を超えると、failed_jobs テーブルに記録されます。
テーブルがない場合は次のコマンドで作成します。
失敗時のクリーンアップ
ジョブにfailed() メソッドを定義すると、失敗したときの後処理を記述できます。
例外によるリトライ停止
例外の種類によってはリトライさせず即座に失敗させたい場合があります。bootstrap/app.php の withExceptions() 内で dontRetry を使って対象の例外クラスを指定します。
dontRetryWhen にクロージャを渡します。クロージャが true を返すとジョブは即座に失敗としてマークされ、リトライされません。
失敗したジョブの一覧確認
失敗したジョブのリトライ
失敗したジョブの削除
よく使うキュードライバ
database ドライバ
追加のミドルウェアなしに使い始められるシンプルなドライバです。jobs テーブルにジョブを保存し、ワーカーがポーリングして処理します。
- 長所: セットアップが簡単、既存のRDBMSをそのまま使える
- 短所: データベースへの負荷が高いため、大量のジョブには不向き
redis ドライバ
本番環境で最もよく使われる高速なドライバです。 インメモリで動作するためデータベースよりもスループットが高く、大量のジョブを処理できます。- 長所: 高速、スケーラブル
- 短所: Redisサーバーの用意が必要
Supervisorによる本番運用
本番環境では、queue:work プロセスが何らかの理由で停止したときに自動で再起動する仕組みが必要です。
Linux環境では Supervisor を使うのが一般的です。
numprocs=2 で2つのワーカープロセスを並列起動します。
設定後に Supervisor を再読み込みします。
実践例: メール送信をキューで処理する
1
ジョブクラスを作成する
2
ジョブの処理を実装する
3
コントローラからディスパッチする
4
ワーカーを起動する
まとめ
キューを使うべきタイミング
キューを使うべきタイミング
- メール・SMS送信
- 画像・動画のリサイズや変換
- 外部APIへのリクエスト
- レポートの生成やCSVエクスポート
- Webhook の送信
開発時のヒント
開発時のヒント
.env で QUEUE_CONNECTION=sync にすると、ジョブはキューを経由せず即時実行されます。
ワーカーを起動しなくても動作確認できるため、開発中は便利です。よく使うコマンドまとめ
よく使うコマンドまとめ