#21 Laravel基礎
キューとジョブで非同期処理を実装する
キューとは
キュー? 処理を非同期で実行する仕組み。メール送信や画像変換など時間のかかる処理をバックグラウンドで行い、レスポンスを速くできる。 は、処理をすぐ実行せずに「後でやること」のリストに追加して、バックグラウンドで実行する仕組みです。
メール送信・画像変換・外部APIへのリクエストなど、時間のかかる処理をキューに投げることでレスポンスを速くできます。
キューの設定
# 📁 .env
QUEUE_CONNECTION=database # database / redis / sync(同期実行)
開発中は sync(すぐに実行)が便利です。本番では database や redis を使います。
database ドライバーを使う場合はジョブを保存するテーブルが必要です。
# ジョブ用テーブルのマイグレーションを生成して実行
php artisan queue:table
php artisan migrate
ジョブを生成する
php artisan make:job SendWelcomeEmail
app/Jobs/SendWelcomeEmail.php が生成されます。
<?php
// 📁 app/Jobs/SendWelcomeEmail.php
namespace App\Jobs;
use App\Mail\WelcomeMail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Mail;
// ShouldQueue を implements するとキューで実行される
class SendWelcomeEmail implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct(
public User $user
) {}
// キューで実行される処理
public function handle(): void
{
Mail::to($this->user)->send(new WelcomeMail($this->user));
}
}
ジョブをキューに投げる
// 📁 app/Http/Controllers/Auth/RegisteredUserController.php
use App\Jobs\SendWelcomeEmail;
public function store(Request $request)
{
$user = User::create([...]);
// dispatch() でキューに追加(すぐには実行されない)
SendWelcomeEmail::dispatch($user);
return redirect()->route('dashboard');
// ← メール送信を待たずにすぐリダイレクト!
}
遅延実行(Delay)
// 10分後にジョブを実行する
SendWelcomeEmail::dispatch($user)->delay(now()->addMinutes(10));
キューワーカーを起動する
ジョブはキューに溜まるだけで、実行するには「ワーカー」プロセスを起動する必要があります。
# キューワーカーを起動(Ctrl+C で停止)
php artisan queue:work
# 1件だけ処理して停止
php artisan queue:work --once
# タイムアウトと最大試行回数を設定
php artisan queue:work --timeout=60 --tries=3
開発中は別のターミナルで queue:work を起動しておくと、ジョブがリアルタイムで処理されます。
ジョブの失敗を処理する
ジョブが最大試行回数を超えて失敗した場合の処理を書けます。
// 📁 app/Jobs/SendWelcomeEmail.php
// 試行回数の上限
public int $tries = 3;
// ジョブが全試行失敗したときに呼ばれる
public function failed(\Throwable $exception): void
{
// Slack通知やログを残す
\Log::error("ウェルカムメール送信失敗: {$this->user->id}", [
'error' => $exception->getMessage(),
]);
}
失敗したジョブは failed_jobs テーブルに記録されます。
# 失敗したジョブを再試行
php artisan queue:retry all
# 失敗したジョブの一覧を確認
php artisan queue:failed
キューを使わずに即時実行したいとき
テストなどで同期実行したい場合:
// dispatchSync() は ShouldQueue でも即時実行する
SendWelcomeEmail::dispatchSync($user);
まとめ
ShouldQueueインターフェースを実装したクラスがキュージョブdispatch()でキューに追加し、ワーカーがバックグラウンドで処理するphp artisan queue:workでキューワーカーを起動するdelay()で遅延実行できる- 失敗したジョブは
failed_jobsテーブルに記録され、queue:retryで再試行できる
次回は通知(Notification)機能を学びます。