Laravel キューとジョブ:非同期アーキテクチャと面接対策 2026
Laravelキューシステムの内部動作、ジョブのバッチ処理・チェイニング・リトライ戦略を解説。2026年の技術面接で問われるキューアーキテクチャの重要ポイントを網羅します。

Laravelキューは、メール送信・ファイルアップロード処理・レポート生成など時間のかかるタスクをバックグラウンドワーカーに委譲するための統一APIを提供します。ユーザーを待たせることなく、アプリケーションはジョブをキューにプッシュして処理を続行します。このメカニズムは、スケーラブルなLaravelアプリケーションの中核に位置します。
Laravelは複数のキューバックエンド(Redis、Amazon SQS、データベース、Beanstalkd)をドライバー非依存の単一APIでサポートしています。ジョブはShouldQueueインターフェースを実装したシリアライズ可能なPHPクラスです。ワーカーがキューからジョブを取得し、デシリアライズしてhandle()メソッドを実行します。失敗したジョブは専用のfailed_jobsテーブルに格納され、リトライや調査が可能です。
Laravelジョブディスパッチの内部動作
ジョブクラスでdispatch()が呼び出されると、Laravelはジョブインスタンス(パブリックプロパティを含む)をシリアライズし、設定されたキュー接続にペイロードをプッシュします。シリアライズされたペイロードには、完全修飾クラス名、シリアライズされたプロパティ、ターゲットキュー名、許可された試行回数やタイムアウトなどのメタデータが含まれます。
キューワーカープロセス(php artisan queue:work)は、キューバックエンドから新しいジョブをポーリングする長寿命デーモンとして動作します。ペイロードを受信すると、ワーカーはジョブをデシリアライズし、サービスコンテナを通じて依存関係を解決し、handle()を呼び出します。
namespace App\Jobs;
use App\Models\Order;
use App\Services\PdfGenerator;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessInvoice implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public int $backoff = 60;
public int $timeout = 120;
public function __construct(
public readonly Order $order
) {}
public function handle(PdfGenerator $pdf): void
{
// Generate PDF invoice for the order
$invoice = $pdf->generate($this->order);
// Store the generated file
$this->order->update([
'invoice_path' => $invoice->path(),
'invoiced_at' => now(),
]);
}
public function failed(\Throwable $e): void
{
// Notify the ops team when invoice generation fails
logger()->error('Invoice generation failed', [
'order_id' => $this->order->id,
'error' => $e->getMessage(),
]);
}
}SerializesModelsトレイトは、Eloquentモデル全体ではなく、モデルの主キーとクラス名のみを保存します。ワーカーがジョブを処理する際に、データベースから最新のモデルを取得します。これにより古いデータの使用を回避し、ペイロードサイズを小さく保ちます。
並列ワークロードのためのジョブバッチング
ジョブバッチングは、複数のジョブを単一のバッチにグループ化し、全体的な進行状況を追跡し、すべてのジョブが完了した時点でコールバックを発火させます。このパターンは、データインポート、一括通知、レポート生成など、最終ステップの前に複数の独立した作業単位を完了させる必要がある場面に適しています。
use App\Jobs\ImportRow;
use Illuminate\Bus\Batch;
use Illuminate\Support\Facades\Bus;
public function import(Request $request)
{
$rows = $this->parseCSV($request->file('data'));
// Create a batch of import jobs, one per CSV row
$batch = Bus::batch(
collect($rows)->map(fn ($row) => new ImportRow($row))
)
->then(function (Batch $batch) {
// All jobs completed successfully
Notification::send(
auth()->user(),
new ImportComplete($batch->totalJobs)
);
})
->catch(function (Batch $batch, \Throwable $e) {
// First failure in the batch
logger()->warning('Batch import partial failure', [
'batch_id' => $batch->id,
'failed' => $batch->failedJobs,
]);
})
->finally(function (Batch $batch) {
// Runs after all jobs finish (success or failure)
Cache::forget("import_lock_{$batch->id}");
})
->allowFailures()
->dispatch();
return response()->json(['batch_id' => $batch->id]);
}Laravel 12ではバッチペイロードにキュー待機時間やワーカー識別情報を含むメタデータが追加されています。allowFailures()メソッドは、単一のジョブ失敗がバッチ全体をキャンセルするのを防ぎます。これは部分的な成功が許容される大規模インポートにおいて重要です。
順次ワークフローのためのジョブチェイニング
バッチングが並列ワークロードを扱うのに対し、チェイニングは順次実行を保証します。チェイン内の各ジョブは、前のジョブが成功した後にのみ実行されます。いずれかのジョブが失敗すると、残りのチェインは中断され、catchコールバックが発火します。
use App\Jobs\ValidatePayment;
use App\Jobs\ReserveInventory;
use App\Jobs\SendConfirmation;
use App\Jobs\GenerateShippingLabel;
use Illuminate\Support\Facades\Bus;
public function processOrder(Order $order): void
{
// Each job runs only after the previous one succeeds
Bus::chain([
new ValidatePayment($order),
new ReserveInventory($order),
new GenerateShippingLabel($order),
new SendConfirmation($order),
])
->onQueue('orders')
->catch(function (\Throwable $e) use ($order) {
// Roll back the order if any step fails
$order->update(['status' => 'failed']);
logger()->error('Order chain failed', [
'order_id' => $order->id,
'step' => $e->getMessage(),
]);
})
->dispatch();
}チェイニングは、ステップの順序が重要なドメインワークフローに適しています。支払い検証は在庫予約の前に完了する必要があり、配送ラベルは確認された在庫に依存します。
Laravelの面接対策はできていますか?
インタラクティブなシミュレーター、flashcards、技術テストで練習しましょう。
横断的関心事のためのキューミドルウェア
キューミドルウェアは、ジョブ実行をレート制限、重複排除、サーキットブレーカーなどの再利用可能なロジックでラップします。これらの関心事をすべてのジョブに埋め込むのではなく、ミドルウェアがジョブをビジネスロジックに集中させます。
namespace App\Jobs\Middleware;
use Closure;
use Illuminate\Support\Facades\RateLimiter;
class RateLimitedJob
{
public function __construct(
private string $key,
private int $maxAttempts = 10,
private int $decaySeconds = 60
) {}
public function handle(object $job, Closure $next): void
{
// Release job back to queue if rate limit exceeded
if (RateLimiter::tooManyAttempts($this->key, $this->maxAttempts)) {
$job->release($this->decaySeconds);
return;
}
RateLimiter::hit($this->key, $this->decaySeconds);
$next($job);
}
}ジョブクラスにmiddleware()メソッドを定義してミドルウェアを適用します:
public function middleware(): array
{
return [
new RateLimitedJob(
key: 'external-api',
maxAttempts: 30,
decaySeconds: 60
),
// Prevent duplicate jobs from running concurrently
(new WithoutOverlapping($this->apiResource->id))
->releaseAfter(300)
->expireAfter(600),
];
}WithoutOverlappingミドルウェアはアトミックロックを使用して、あるキーで識別されるジョブのインスタンスが一度に1つだけ実行されることを保証します。レート制限と組み合わせることで、重複処理とAPIスロットリングの両方を防止します。
失敗したジョブの処理とリトライ戦略
本番環境のキューシステムには堅牢な障害処理が必要です。Laravelは失敗したジョブをfailed_jobsテーブルに完全なペイロード、例外トレース、障害を生成したキュー/コネクション情報とともに保存します。各ジョブクラスのfailed()メソッドは、すべてのリトライ試行が完了した後に実行されます。
ジョブごとにリトライ動作を設定することで、きめ細かな制御が可能です:
class SyncExternalData implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 5;
// Exponential backoff: 10s, 30s, 60s, 120s, 300s
public function backoff(): array
{
return [10, 30, 60, 120, 300];
}
// Job-specific timeout
public int $timeout = 180;
// Maximum exceptions before marking as failed
public int $maxExceptions = 3;
public function retryUntil(): \DateTime
{
// Keep retrying for up to 24 hours
return now()->addHours(24);
}
public function handle(): void
{
$response = Http::timeout(30)
->retry(2, 1000)
->get('https://api.vendor.com/data');
if ($response->failed()) {
// Release back to queue with delay for transient failures
$this->release(60);
return;
}
DataSync::process($response->json());
}
public function failed(\Throwable $e): void
{
Notification::route('slack', config('services.slack.ops_channel'))
->notify(new SyncFailed($e));
}
}面接では$tries、$maxExceptions、retryUntil()の違いが重要です。$triesは手動リリースを含むすべての試行をカウントします。$maxExceptionsは未処理の例外のみをカウントします。retryUntil()は試行回数に関係なく時間枠を設定します。
キューワーカーの管理とデプロイ
本番環境のキューワーカーには、プロセス監視、デプロイ時のグレースフルリスタート、リソース管理が必要です。Supervisorがワーカーを稼働させ続けるための標準ツールです。
; /etc/supervisor/conf.d/laravel-worker.conf
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/app/artisan queue:work redis --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopwaitsecs=3600
user=www-data
numprocs=4
redirect_stderr=true
stdout_logfile=/var/log/worker.log
stopasgroup=true
killasgroup=trueデプロイ時の重要な考慮事項:
- グレースフルリスタート:
php artisan queue:restartはワーカーに現在のジョブを完了してからリスタートするよう信号を送ります。デプロイ中のジョブ破損を防止します。 - 最大時間/ジョブ数:
--max-time=3600と--max-jobs=1000はワーカープロセスを定期的にリサイクルすることでメモリリークを防止します。 - スリープ間隔:
--sleep=3は空のキューを再ポーリングするまでのワーカーの待機時間を制御します。値を小さくすると応答性は向上しますが、データベース/Redisの負荷も増加します。 - 複数キュー:
--queue=critical,default,lowは優先順位に従ってキューを処理します。ワーカーはcriticalキューを完全に消化してからdefaultに移ります。
Laravel 12.37ではバックグラウンドキュー接続が導入され、Concurrently::defer()を使用してジョブを遅延実行できます。このドライバーはジョブをシリアライズして別のPHPプロセスで実行します。完全なキューインフラストラクチャを必要としない軽量ジョブに適しています。
ユニークジョブと暗号化ペイロード
本番環境と面接の議論で頻繁に登場する2つのパターンがあります。特定のキーに対してジョブが一度だけ実行されることを保証するパターンと、ジョブペイロード内の機密データを保護するパターンです。
use Illuminate\Contracts\Queue\ShouldBeUnique;
class RebuildSearchIndex implements ShouldQueue, ShouldBeUnique
{
// Lock duration in seconds
public int $uniqueFor = 3600;
public function __construct(
public readonly string $indexName
) {}
// Unique key scopes the lock to this specific index
public function uniqueId(): string
{
return $this->indexName;
}
public function handle(): void
{
SearchIndex::rebuild($this->indexName);
}
}機密データ(ユーザー認証情報、決済トークン)を含むジョブには、ShouldBeEncryptedインターフェースがシリアライズされたペイロード全体を保存時に暗号化します:
use Illuminate\Contracts\Queue\ShouldBeEncrypted;
class ProcessPayment implements ShouldQueue, ShouldBeEncrypted
{
public function __construct(
private string $paymentToken,
private float $amount
) {}
public function handle(PaymentGateway $gateway): void
{
$gateway->charge($this->paymentToken, $this->amount);
}
}ペイロードはRedisやデータベースに保存される前にアプリケーションキーで暗号化されます。ワーカーはデシリアライズ前に自動的に復号します。
Laravelキューに関する面接頻出質問
技術面接では、表面的なAPI知識を超えたキューアーキテクチャの理解が問われます。
キューに入れたジョブが削除済みのEloquentモデルを参照している場合、何が起こるか?
SerializesModelsを使用している場合、ワーカーはジョブ処理時にIDでモデルを取得しようとします。モデルが存在しない場合、LaravelはModelNotFoundExceptionをスローします。これをグレースフルに処理するには、$deleteWhenMissingModelsプロパティをtrueに設定します。ジョブは失敗する代わりにキューから静かに削除されます。
ShouldBeUniqueとWithoutOverlappingミドルウェアの違いは?
ShouldBeUniqueは、同じユニークキーを持つジョブがすでにキューに存在する場合、ジョブのディスパッチを防止します。WithoutOverlappingはディスパッチを許可しますが、同時実行を防止します。同じキーを持つジョブが既に実行中の場合、新しいインスタンスはキューに戻されます。異なる問題を解決するものであり、組み合わせて使用できます。
retryUntil()が$triesより好まれる場面は?
回復時間が予測できない外部サービスと連携するジョブにはretryUntil()を使用します。固定のリトライ回数($tries = 3)は短時間の障害中に試行を使い果たす可能性があります。retryUntil()は時間枠(例:24時間)を設定し、サービスが回復するか時間枠が期限切れになるまでバックオフ付きでリトライを続けます。
複数キューでのキュー優先順位の仕組みは?
queue:work --queue=critical,default,lowで優先順位システムを構築します。ワーカーはcriticalキューを完全に消化してからdefaultをチェックし、defaultの後にlowをチェックします。ピーク負荷時には低優先度ジョブが飢餓状態になる可能性があります。厳格なSLAが必要な場合は、キューごとに専用ワーカーを配置する方が良い保証を提供します。
今すぐ練習を始めましょう!
面接シミュレーターと技術テストで知識をテストしましょう。
まとめ
- LaravelキューはRedis、SQS、データベース、およびLaravel 12.37の新しいバックグラウンド接続をサポートするドライバー非依存APIの背後にキューバックエンドを抽象化します
- ジョブバッチングは集合的な進行状況追跡で並列ワークロードを処理し、チェイニングはドメインワークフローの順次実行を強制します
- キューミドルウェア(レート制限、
WithoutOverlapping)は横断的関心事をジョブのビジネスロジックから分離します - 失敗したジョブの処理は
$tries、$maxExceptions、retryUntil()、指数バックオフを組み合わせた回復力のあるリトライ戦略を実現します ShouldBeUniqueは重複ディスパッチを防止し、ShouldBeEncryptedは保存時の機密ペイロードを保護します- 本番ワーカーにはSupervisor、デプロイ時のグレースフルリスタート、
--max-timeと--max-jobsによるメモリ管理が必要です - 面接準備では、ディスパッチ時のユニーク性と実行時のロックの区別、モデルシリアライズの動作、キュー優先順位の飢餓問題をカバーする必要があります
Laravel面接質問の実践練習として、SharpSkillの問題集ではキュー、ミドルウェア、Eloquentパターンを詳細な解説付きで提供しています。
今すぐ練習を始めましょう!
面接シミュレーターと技術テストで知識をテストしましょう。
タグ
共有
関連記事

LaravelとPHPの面接質問:2026年版トップ25
LaravelとPHPの面接で最も頻出する25の質問を解説します。Eloquent ORM、ミドルウェア、キュー、テスト、アーキテクチャパターンについて、詳細な回答とコード例を掲載しています。

Laravel Middleware徹底解説:認証、レート制限、カスタムミドルウェアの実装ガイド
Laravelミドルウェアの仕組みを基礎から応用まで解説します。認証ミドルウェア、throttleによるレート制限、カスタムミドルウェアの作成方法、そして本番環境で使える実践的なミドルウェアパターンを具体的なコード例とともに紹介します。

Eloquent ORM:Laravel のためのパターンと最適化
高度なパターンと最適化テクニックで Eloquent ORM を使いこなします。Laravel アプリケーションのためのイーガーローディング、クエリスコープ、アクセサ、ミューテータ、パフォーマンス。