Laravel における Queue の利用 中編 – 非同期キューの管理

Queue は Laravel 上で非同期な処理を実行するための行列システムです。前編では、ジョブを利用してキューの実装を行う方法の概要を紹介しました。今回は、非同期キューの管理方法を紹介していきます。

ジョブの処理では、デフォルトの環境変数を QUEUE_DRIVER=syncQUEUE_DRIVER=database などのようにして、キューのドライバを設定することで、非同期なキューの処理を行う事ができるようになります。

非同期なキュー処理においては様々なタスク処理上のオプションが利用可能となるため、その一部を紹介していきます。

キュードライバの設定

Laravel では 非同期Queue のドライバとして様々なものが用意されています。

  • database
  • redis
  • Beanstalkd
  • Amazon SQS

その他、デフォルトで設定されている sync ドライバや 直ちにジョブを捨てる null ドライバも利用可能です。

詳細は Laravel の公式ドキュメントを参照ください。

Queues – Laravel – The PHP Framework For Web Artisans

キューが 発行される先 は通常 環境変数 QUEUE_DRIVER に沿いますが、 onConnection を利用して、設定済みの特定のキューにジョブを発行することも可能です。

ProcessPodcast::dispatch()->onConnection('sqs');

キューを処理する際にも、どのドライバのキューを処理するのか引数で指定することができます。

$ php artisan queue:work redis

名前付きキューの利用

名前付きキューを利用することでタスクの処理を別々のコマンドで管理できるようになっています。

通常ジョブは default という名前でキューに登録されますが、以下のような形でジョブ発行時に名前を指定して、名前付きキューにジョブを登録することもできるようになっています。

ProcessPodcast::dispatch($podcast)->onQueue('high');

キューを実行する際にコマンドオプションqueue を指定することで名前付きキューの処理を行うことができます。

$ php artisan queue:work --queue=high,low

queue オプションには上記のように , 区切りで複数のキュー名を渡すこともできるようになっています。複数のキューを渡す場合、優先度の高い順にキュー名を記述することで、先に記述されたキューの処理が完全に完了してから 2番目以降の処理が行われるようになります。

ジョブの遅延実行

ジョブの有効期限を設定することも可能です。 xx 時になったら処理をする、といった形で日時を指定する際には delay を設定して処理を指定することが可能です。

ProcessPodcast::dispatch()->delay(now()->addMinutes(10));

メールの一斉送信によるサイト閲覧負荷を下げたい場合など、キュー処理能力とは別の理由でディレイを掛けたいときに非常に役立ちます。

ジョブのテスト

ジョブが発行されることをテストで検証したい場合、以下のような形でテストを実施することができます。

<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Jobs\ShipOrder;
use Illuminate\Support\Facades\Queue;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;

class ExampleTest extends TestCase
{
    public function testOrderShipping()
    {
        Queue::fake();

        // Perform order shipping...

        Queue::assertPushed(ShipOrder::class, function ($job) use ($order) {
            return $job->order->id === $order->id;
        });

        // Assert a job was pushed to a given queue...
        Queue::assertPushedOn('queue-name', ShipOrder::class);

        // Assert a job was pushed twice...
        Queue::assertPushed(ShipOrder::class, 2);

        // Assert a job was not pushed...
        Queue::assertNotPushed(AnotherJob::class);
    }
}

Queue::fake(); が実行されたタイミングで、 キューが実際に発行されることがなくなり、また assertPushed などのメソドを利用して、 キューが発行されたかどうかの検証を行うことができるようになります。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です