Laravel 5.0 キュー

設定

Laravelのキューコンポーネントは、様々なキューサービス共通のAPIを提供しています。キューによりメール送信のような時間を費やす処理を夜中まで遅らせることが可能です。これによりアプリケーションのリクエストを徹底的に引き上げることができます。

キューの設定ファイルはconfig/queue.phpです。このファイルには、フレームワークに含まれているそれぞれのドライバーへの接続設定があります。それには、データベース、BeanstalkdIronMQAmazon SQSRedis、null、同期(ローカル用途)ドライバーが含まれています。nullキュードライバーはキューされたジョブが実行されないように、破棄するだけです。

データベースキューテーブル

databaseキュードライバーを使用するには、ジョブを記録するためのデータベーステーブルが必要です。このテーブルを作成するマイグレーションは、queue:table Artisanコマンドにより生成できます。

php artisan queue:table

キューに必要なパッケージ

前記のキュードライバーを使用するには、以下の対応するパッケージをcomposer.jsonに付け加えることが必要です。

基本的な使用法

キューへジョブ登録

アプリケーションにキュー投入できる全ジョブはApp\Commandsディレクトリーに保存します。新しいキュー投入コマンドを生成するには、Artisan CLIコマンドを使用します。

php artisan make:command SendEmail --queued

新しいジョブをキューに投入するには、Queue::pushメソッドを使用します。

Queue::push(new SendEmail($message));

注目: この例では、Queueファサードを直接使用しています。しかし、通常キューコマンドをディスパッチするには、コマンドバスの方が好まれます。このページでは、以降も続けてQueueファサードを使用しますが、アプリケーション上でキューと同期コマンドの両方を起動することができますので、コマンドバスにも習熟してください。

make:command Artisanコマンドのデフォルトは、「自己処理」コマンドを生成します。つまり、handleメソッドがコマンド自身へ含まれています。このメソッドはキューにより、ジョブが実行されるときに呼び出されます。handleメソッドには必要な依存をタイプヒントで指定でき、サービスコンテナが自動的に注入します。

public function handle(UserRepository $users)
{
    //
}

コマンドから独立したハンドラークラスを持たせたい場合は、--handlerフラッグをmake:commandコマンドに付けます。

php artisan make:command SendEmail --queued --handler

生成されるハンドラーは、App\Handlers\Commandsに置かれ、IoCコンテナにより依存解決されます。

ジョブのキューを指定

どのキューにジョブを登録するのかを指定することもできます。

Queue::pushOn('emails', new SendEmail($message));

同一データ本体の複数ジョブ投入

同じデーターを複数のキュージョブに送る必要がある場合は、Queue::bulkメソッドを使用して下さい。

Queue::bulk([new SendEmail($message), new AnotherCommand]);

ジョブ実行の遅延

キュージョブの実行を遅らせたい場合もあるでしょう。例えば、サインアップの15分後に顧客へメールを送信するジョブをキューしたい場合などです。この場合、Queue::laterメソッドを使用して下さい。

$date = Carbon::now()->addMinutes(15);

Queue::later($date, new SendEmail($message));

この例の中で、ジョブに希望する遅延実行時間を指定するために、Carbonライブラリーを使用しています。もしくは、整数で遅らせたい秒数を渡すこともできます。

注目: Amazon SQSサービスには、遅延900秒(15分)という制限があります。

キューとEloquentモデル

もし、キュージョブがコンストラクターにEloquentモデルを受け付ける場合、そのモデルのIDだけがキューへシリアライズされます。実際にそのジョブが処理される時に、キューシステムはデータベースからモデルの完全なインスタンスを自動的に再取得します。これにより、Eloquentのモデルインスタンスを完全にシリアライズすると持ち上がる問題を防ぐことができ、アプリケーションに対する完全な透過性も保てます。

処理済みのジョブの削除

ジョブを処理し終えた時、キューから削除する必要があります。ジョブの実行中に例外が投げられなければ、これは自動的に行われます。

ジョブを自分でdeletereleaseしたければ、Illuminate\Queue\InteractsWithQueueトレイトが提供するreleasedeleteメソッドで行えます。releaseメソッドは引数をひとつだけ取り、再度実行するまでに待つ秒数を指定します。

public function handle(SendEmail $command)
{
    if (true)
    {
        $this->release(30);
    }
}

ジョブのキュー再投入

処理中に例外が投げられると、再実行できるよう自動的にキューに戻されます。アプリケーションで許可されている最高実行回数まで、そのジョブは繰り返されます。最高実行回数は、queue:listenqueue:work Artisanコマンドへ、--triesスイッチにより指定されます。

実行回数の取得

ジョブの処理中に例外が起きた場合、そのジョブは自動的にキューに再登録されます。そのジョブを実行しようとした試行回数をattemptsメソッドで調べることができます。

if ($this->attempts() > 3)
{
    //
}

注目: このメソッドを呼び出すには、Illuminate\Queue\InteractsWithQueueトレイトを使用する必要があります。

クロージャーのキュー

もしくはキューにクロージャーを登録することも可能です。これは手軽にシンプルなタスクをキュー登録する必要がある場合に大変便利です。

キューのクロージャー登録

Queue::push(function($job) use ($id)
{
    Account::delete($id);

    $job->delete();
});

注目: useを使用し、キューするクロージャーでオブジェクトを使用できるように渡す代わりに主キーを渡し、キュージョブの中で関連するモデルを再取得する設計をしてください。これにより、シリアライズの予期しない影響を防ぐことができます。

Iron.ioのPushキューを利用する場合、キューのクロージャーで追加の予防策を取る必要があります。キューメッセージを受け取った時点でそのキューが本当にIron.ioからのリクエストであるかをチェックしてください。例えば、Pushキューの受け取りURLをhttps:://yourapp.com/queue/receive?token=秘密のトークンのような形式で登録します。次に、キューリクエストでmarshalメソッドを実行する前に、秘密のトークンの値をアプリケーションでチェックします。

キューリスナーの実行

LaravelのArtisanは、新しくキューに保存されたジョブを実行するコマンドを含んでいます。queue:listenコマンドで、このタスクを実行できます。

キューリスナーの開始

php artisan queue:listen

リスナーに使用するキュー接続を指定することもできます。

php artisan queue:listen connection

このタスクを一度開始したら、手動で停止しない限り実行を続けることに注意してください。Supervisorのようなプロセスモニターを利用し、キューリスナーが確実に動作し続けるようにしてください。

listenコマンドにキューのプライオリティーを設定するため、キュー接続をカンマ区切りで指定することもできます。

php artisan queue:listen --queue=high,low

この例で、high-connectionlow-connectionのジョブを実行する前にいつも処理されます。

ジョブのタイムアウト時間を指定する

それぞれのジョブの実行時間を秒数で指定することもできます。

php artisan queue:listen --timeout=60

キューのスリープ時間を指定する

さらに、新しいジョブをポーリングする前に、待ち秒数を指定することもできます。

php artisan queue:listen --sleep=5

キューにジョブがない場合のみ、キューがスリープすることに注意して下さい。もし、ジョブが存在しているなら、キューはスリープせずに処理を続けます。

キューの最初のジョブを実行する

キューの最初のジョブだけを実行するには、queue:workコマンドを使用してください。

php artisan queue:work

デーモンキューワーカー

queue:workはフレームワークを再起動せずに連続してジョブを処理し続けるように、キューワーカーを強制するための、--daemonオプションも備えています。これにより、queue:listenと比較すると、CPU使用率を大幅に引き下げることができますが、デプロイ中は現在実行中のジョブのキューを空にするために、複雑な手順の追加が必要になります。

キュー・ワーカーをデーモンモードで開始するためには、--daemonフラッグを使用します。

php artisan queue:work connection --daemon

php artisan queue:work connection --daemon --sleep=3

php artisan queue:work connection --daemon --sleep=3 --tries=3

ご覧の通り、queue:workコマンドはqueue:listenで使用できるものと、ほぼ同じオプションをサポートしています。php artisan help queue:workコマンドで全オプションを表示できます。

デーモンキューワーカーによるデプロイ

アプリケーションをデーモン・キュー・ワーカーでデプロイする、一番簡単な方法は、デプロイを開始するときに、アプリケーションをメンテナンスモードにすることです。php artisan downコマンドにより切り替えられます。アプリケーションをメンテナンスモードにすると、Laravelは新しいジョブをキューに受け付けなくなりますが、存在しているジョブの処理は続けます。

ワーカーを一番簡単に再起動するには、デプロイスクリプトの中に、次のコマンドを含めてください。

php artisan queue:restart

このコマンドは、現在のジョブの処理が終了した後、全キューワーカーを再起動するように指示します。

注意: このコマンドは再起動のスケジュールするため、キャッシュシステムを利用しています。デフォルト状態では、APCuはCLIコマンドのために動作しません。APCuを使用する場合、apc.enable_cli=1をAPCu設定に追加してください。

デーモンキューワーカーのコーディング

デーモンキューワーカーは、各ジョブを処理する前にフレームワークを再起動しません。そのため、多くのリソースを使用するジョブを完了する前に、それらを開放するように気をつけてください。例えば、GDライブラリーを使用し、画像処理を行う場合、完了したらimagedestroyでメモリを開放する必要があるでしょう。

同様に、デーモンが長時間動作し、使用され続ければデータベース接続は切断されるでしょう。新しい接続を行うために、DB::reconnectメソッドを使う必要が起きるでしょう。

Pushキュー

デーモンやバックグラウンドリスナーを走らせなくても、Pushキューを使えばLaravel5のキュー機能を存分に利用できます。現在、PushキューはIron.ioドライバーでしかサポートされていません。開始する前にIron.ioのアカウントを作成し、Ironの認証データーをconfig/queus.php設定ファイルに追加してください。

Pushキュー購読の登録

次に、新しく登録されたキュージョブを受け取るエンドポイントURLをqueue::subscribe Artisanコマンドで登録します。

php artisan queue:subscribe queue_name queue/receive

php artisan queue:subscribe queue_name http://foo.com/queue/receive

これでIronダッシュボードへログインすると、新しいPushキューが購読URLと共に表示されます。指定したキューに対し、好きなだけURLを購読することもできます。次に、queue/receiveエンドポイントへのルートを生成し、Queue::marshalメソッドからのレスポンスをリターンしてください。

Route::post('queue/receive', function()
{
    return Queue::marshal();
});

marshalメソッドは正しいジョブハンドラークラスが実行されるように取り計らいます。Pushキューへのジョブを実行するには、Queue::pushメソッドと同様にキューの使用手順に従い利用してください。

失敗したジョブ

物事はうまく行かない場合もありますので、キュージョブが失敗することも想定できます。でも、心配ありません。最高な人たちも失敗はするものです! Laravelは指定した回数ジョブを再実行する便利な方法を用意しています。この回数実行してもうまく行かない場合は、faild_jobsテーブルに登録されます。この失敗したジョブのテーブル名は、config/queue.php設定ファイルで指定できます。

faild_jobsテーブルのマイグレーションを生成するには、queue:faild-tableコマンドを実行して下さい。

php artisan queue:failed-table

ジョブ再実行の最大回数を指定するには、queue:listenコマンドに--triesスイッチを付け実行して下さい。

php artisan queue:listen connection-name --tries=3

キュージョブが失敗した時に呼び出されるイベントのリスナーを登録したい場合は、Queue::failingメソッドを使って下さい。このイベントは、メールかHipChatであなたのチームに通知するために便利でしょう。

Queue::failing(function($connection, $job, $data)
{
    //
});

キュージョブクラスへ直接failedメソッドを定義すると、失敗が起きたときに指定されたアクションが実行されるようになります。

public function failed()
{
    // ジョブが失敗した時に呼ばれる…
}

失敗したジョブの再実行

失敗したジョブを全部確認するには、queue:failed Arisanコマンドを利用します。

php artisan queue:failed

queue:failedコマンドにジョブIDを指定すれば、接続、キュー、失敗した時間がリストされます。ジョブIDは失敗したジョブを再実行する場合にも使用します。例えば、IDが5の失敗したジョブを再実行するには、以下のコマンドを実行します。

php artisan queue:retry 5

失敗したジョブを削除するには、queue:forgetコマンドを使います。

php artisan queue:forget 5

失敗したジョブを全部消去するには、queue:flushコマンドを使用します。

php artisan queue:flush

ドキュメント章別ページ

Artisan CLI

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる