0
0

はじめに

今回はLaravelのジョブとキューを活用して効率的に非同期処理を実行する方法について解説していきます
ジョブとキューの基本概念から実際の実装方法、設定、活用例、トラブルシューティング、ベストプラクティスを見ていこうと思います

ジョブとキューの基本概念

ジョブ(Jobs)とは

ジョブは、非同期で実行される処理単位を指します
例えば、ユーザー登録時のメール送信、画像のリサイズ、データのバックアップなどが該当します
ジョブをキューに投入することで、即時ではなくバックグラウンドで処理を行うことができます

キュー(Queue)とは

キューは、ジョブを管理・処理するための仕組みです
ジョブはキューに投入され、指定されたワーカーによって非同期的に実行されます

ジョブの作成方法と実行方法

ジョブの作成

Laravelでジョブを作成するには、以下のコマンドを実行します

php artisan make:job SendWelcomeEmail

このコマンドにより、app/jobs配下にジョブクラスが作成されます

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldBeUnique;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

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

    /**
     * Create a new job instance.
     */
    public function __construct()
    {
        //
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        //
    }
}

例えば、ユーザー登録時に歓迎メールを送信するジョブを作成します

<?php
namespace App\Jobs;

use Mail;
use App\Mail\WelcomeEmail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class SendWelcomeEmail 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 WelcomeEmail($this->user));
  }
}

ジョブの実行

ジョブを実行するには、以下のようにディスパッチします

use App\Jobs\SendWelcomeEmail;

$user = User::find(1);
SendWelcomeEmail::dispatch($user);

これにより、ジョブがキューに投入され、バックグラウンドで処理されるようになります

キューの設定方法と使用方法

キューの設定

Laravelは複数のキュードライバをサポートしています
デフォルトではsyncドライバが設定されていますが、databaseredissqsなども利用可能です
まず、config/queue.phpを編集して使用するドライバを設定します

'default' => env('QUEUE_CONNECTION', 'database'),

次に、.envファイルでキュードライバを指定します

QUEUE_CONNECTION=database

databaseドライバを使用する場合、テーブルを作成する必要があります

php artisan queue:table
php artisan migrate

キューの使用

キューワーカを使用してジョブを処理します

php artisan queue:work

このコマンドにより、キューに投入されたジョブが順次処理されます

実際のプロジェクトにおける活用例

ユーザー登録時の歓迎メール送信

前述のジョブをユーザー登録時に実行する例です
ユーザー登録コントローラでジョブをディスパッチします

use App\Jobs\SendWelcomeEmail;

public function register(Request $request /** フォームリクエストがユーザー情報のみの前提 **/)
{
  // ユーザー登録処理
  $user = User::create($request->all());

  // ジョブをディスパッチ
  SendWelcomeemail::dispatch($user);

  return response()->json(['message' => '登録が完了しました。']);

画像のリサイズ

画像アップロード時にリサイズ処理を非同期で行うジョブを作成します

<?php

namespace App\Jobs;

use Image;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

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

  protected $imagePath;
  private $width = 800;
  private $height = 600;
  

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

  public function handle()
  {
    $width = 800;
    
    $image = Image::make($this->imagePath)->resize($this->width, $this->height);
    $image->save($this->imagePath);
  }
}

ジョブを実行

use App\Jobs\ResizeImage;

public function upload(Request $request)
{
  $path = $request->file('image')->store('images');

  // リサイズジョブをディスパッチ
  ResizeImage::dispatch($path);

  return response()->json(['message' => '画像がアップロードされました。']);
}

トラブルシューティングとベストプラクティス

トラブルシューティング

  1. ジョブが実行されない
    • キューワーカが正しく機能しているかを確認
    • キュー設定が正しいかを確認
  2. ジョブが失敗する
    • ログファイルを確認し、エラーメッセージを特定
    • failed_jobsテーブルを使用して失敗したジョブを管理

ベストプラクティス

  1. ジョブの再試行
    • ジョブが失敗した場合の再試行を設定します
public function retryUntil()
{
  return now()->addMinutes(10); // 10分後に再試行
}
  1. ジョブの優先度設定
    • 重要なジョブを優先的に処理するために、キュー名を指定します
SendWelcomeEmail::dispatch($user)->onQueue('high');
  1. トランザクションの使用
    • データベース操作を伴うジョブでは、トランザクションを使用してデータの整合性を保ちます
DB::transaction(function() use ($user) {
  SendWelcomeEmail::dispatch($user);
});

まとめ

Laravelのジョブとキューを活用することで、非同期処理やバックグラウンドタスクを効率的に実装できます
実際のプロジェクトでジョブとキューを適用して効率的なアプリケーションを作っていきましょう!
僕も個人開発のLaravelプロジェクトに組み込んでみたいと思います!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0