【Laravel】ジョブとキューを活用して重い処理を非同期化する方法

【Laravel】ジョブとキューを活用して重い処理を非同期化する方法 Laravel

Laravelでは、メール送信やファイルアップロード、外部APIとの通信などの重い処理を「ジョブ」と「キュー」を使って非同期化することができます。これにより、ユーザー体験を損なうことなくバックグラウンドで処理を進めることが可能になります。

この記事では、Laravelのキューシステムを用いて処理を非同期に行うための手順を、ジョブの作成からキューワーカの実行まで丁寧に解説します。

ジョブとキューとは?

Laravelのジョブとは、特定の処理内容をまとめたクラスであり、キューとはそのジョブを後で実行するための仕組みです。ジョブは同期的にすぐ実行することもできますが、キューに送信することでバックグラウンドで処理させることができます。

例えば、ユーザー登録時に完了メールを送る場合、通常はその処理が終わるまで待つ必要があります。しかし、メール送信をジョブとしてキューに積めば、登録処理は即完了し、メールは別プロセスで送信されるようになります。

環境設定:.envファイルのキュードライバを設定

まずは.envファイルでキュードライバを設定します。開発環境ではdatabaseが手軽でおすすめです。

QUEUE_CONNECTION=database

config/queue.phpで設定を確認しておきましょう。databaseドライバを使う場合は、キューテーブルを作成する必要があります。

php artisan queue:table
php artisan migrate

ジョブの作成と処理内容の定義

次に、ジョブを作成します。ここでは例として、完了メールを送る処理を非同期にするケースを想定します。

php artisan make:job SendCompleteMail

作成されたapp/Jobs/SendCompleteMail.phpを編集して、メール送信処理を記述します。

namespace App\Jobs;

use App\Mail\CompleteMail;
use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\Mail;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class SendCompleteMail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $user;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function handle()
    {
        Mail::to($this->user->email)->send(new CompleteMail($this->user));
    }
}

このジョブはShouldQueueを実装しているため、キューに積まれた後、非同期でhandle()が実行されます。

コントローラーでジョブをディスパッチ

ジョブの処理内容ができたら、コントローラーなどからジョブをキューに投入(ディスパッチ)します。

use App\Jobs\SendCompleteMail;

public function register(Request $request)
{
    $user = User::create($request->all());

    SendCompleteMail::dispatch($user);

    return response()->json(['message' => '登録完了']);
}

この時点で、ジョブはjobsテーブルにレコードとして登録されますが、まだ実行はされていません。

キューワーカを起動してジョブを処理する

最後に、キューワーカを起動して、キューに溜まったジョブを順に処理します。

php artisan queue:work

常駐させる場合は、supervisordなどのプロセス管理ツールと組み合わせることで、ワーカープロセスを常に稼働させることができます。

ディレイや再試行回数の設定

ジョブには、実行の遅延や最大試行回数なども設定可能です。

public $tries = 3;
public $timeout = 10;

また、delay()を使えば数秒後に処理を行うことも可能です。

SendCompleteMail::dispatch($user)->delay(now()->addSeconds(30));

まとめ

ジョブとキューは、Laravelの中でも非常に強力な非同期処理の仕組みです。重たい処理をキューに逃がすことで、レスポンスを高速化し、ユーザー体験を大きく向上させることができます。導入も比較的簡単なので、ぜひプロジェクトに取り入れてみてください。