設定
Laravelのキューコンポーネントは様々なキューサービスに共通のAPIを提供しています。キューによりメール送信のような時間を費やす処理を夜中まで遅らせることが可能です。これによりアプリケーションのリクエストを徹底的に引き上げることができます。
キュー設定ファイルはapp/config/queue.php
です。このファイルには、フレームワークに含まれているそれぞれのドライバーへの接続設定があります。それには、Beanstalkd、IronMQ、Amazon SQS、Redis、synchronous(同期ドライバー、ローカルでの使用)ドライバーが含まれています。
前記のキュードライバーを使用するには、以下の対応するパッケージをcomposer.jsonに付け加えることが必要です。
- Beanstalkd:
pda/pheanstalk ~2.0
- Amazon SQS:
aws/aws-sdk-php
- IronMQ:
iron-io/iron_mq
基本的な使用法
キューにジョブを登録する
新しいジョブをキューに入れるには`Queue::push'メソッドを使います。
Queue::push('SendEmail', array('message' => $message));
ジョブハンドラーを定義する
push
メソッドの最初の引数は、ジョブを処理するクラス名です。2番目はハンドラーに渡すデーターの配列です。ハンドラは以下のように定義します。
class SendEmail {
public function fire($job, $data)
{
//
}
}
キューに登録されたデーターの配列と共に、ジョブのインスタンスを受け取るための、fire
メソッドが最低必要であることに注意してください。
カスタムハンドラーメソッドを指定する
もしfire
以外のメソッドで処理したい場合は、登録するジョブにメソッドも指定してください。
Queue::push('SendEmail@send', array('message' => $message));
ジョブにキュー/チューブを指定する
どのキュー/チューブにジョブを登録するのかを指定することもできます。
Queue::push('SendEmail@send', array('message' => $message), 'emails');
同じペイロードを複数のジョブに渡す
同じデーターを複数のキュージョブに送る必要がある場合は、Queue::bulk
メソッドを使用して下さい。
Queue::bulk(array('SendEmail', 'NotifyUser'), $payload);
ジョブの実行を遅らせる
場合によってはキュージョブの実行を遅らせたいこともあるでしょう。例えば、サインアップの15分後に顧客へメールを送信するジョブをキューしたい場合です。この場合、Queue::lator
メソッドを使用して下さい。
$date = Carbon::now()->addMinutes(15);
Queue::later($date, 'SendEmail@send', array('message' => $message));
この例の中で、ジョブに希望する遅延実行時間を指定するために、Carbonライブラリーを使用しています。もしくは、整数で遅らせたい秒数を渡すこともできます。
注目: Amazon SQSサービスの場合、遅延は900秒(15分)の制限があります。
処理済みのジョブを削除する
あるジョブを処理したら、それはキューから削除されなくてはなりません。ジョブインスタンスのdelete
メソッドでこれを行います。
public function fire($job, $data)
{
// Process the job...
$job->delete();
}
キューに再登録する
もしジョブを再実行するため、ジョブに登録し直すのであれば、release
メソッドを使用してください。
public function fire($job, $data)
{
// Process the job...
$job->release();
}
そのジョブが再実行されるまでの間隔を秒で指定することもできます。
$job->release(5);
実行回数を調べる
ジョブの処理中に例外が起きた場合、そのジョブは自動的にキューに再登録されます。そのジョブを実行しようとした試行回数をattempts
メソッドで調べることができます。
if ($job->attempts() > 3)
{
//
}
ジョブIDにアクセスする
ジョブ識別子にもアクセスできます。
$job->getJobId();
クロージャーのキュー
もしくはキューにクロージャーを登録することも可能です。これは手軽にシンプルなタスクをキュー登録する必要がある場合に大変便利です。
キューにクロージャーを登録する
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-connection
はlow-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キューでデーモンやバックグラウンドリスナーを走らせなくてもLaravel4のキュー機能を存分に利用できます。現在、PushキューはIron.ioドライバーでしかサポートされていません。開始する前にIron.ioのアカウントを作成し、Ironの認証データーをapp/config/queus.php
設定ファイルに追加してください。
Pushキューの購読を登録する
次に、新しく登録されたキュージョブを受け取るエンドポイントURLをqueue::subscribe
Artisanコマンドで登録します。
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
テーブルに登録されます。この失敗したジョブのテーブル名は、app/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)
{
//
});
失敗したジョブを全部確認するには、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