イントロダクションIntroduction
Laravelのキューサービスは、Beanstalk、Amazon SQS、Redis、さらにはリレーショナル・データベースなど様々なキューバックエンドに対し共通のAPIを提供しています。キューによりメール送信のような時間を費やす処理を遅らせることが可能です。時間のかかるタスクを遅らせることで、よりアプリケーションのリクエストをドラマチックにスピードアップできます。Laravel queues provide a unified API across a variety of different queue backends, such as Beanstalk, Amazon SQS, Redis, or even a relational database. Queues allow you to defer the processing of a time consuming task, such as sending an email, until a later time. Deferring these time consuming tasks drastically speeds up web requests to your application.
キューの設定ファイルはconfig/queue.php
です。このファイルにはフレームワークに含まれているそれぞれのドライバーへの接続設定が含まれています。それにはデータベース、Beanstalkd、Amazon SQS、Redis、ジョブが即時に実行される同期(ローカル用途)ドライバーが含まれています。 null
キュードライバはキューされたジョブが実行されないように、破棄するだけです。The queue configuration file is stored in config/queue.php
. In this file you will find connection configurations for each of the queue drivers that are included with the framework, which includes a database, Beanstalkd[https://kr.github.io/beanstalkd/], Amazon SQS[https://aws.amazon.com/sqs/], Redis[http://redis.io], and a synchronous driver that will execute jobs immediately (for local use). A null
queue driver is also included which simply discards queued jobs.
接続 Vs. キューConnections Vs. Queues
Laravelのキューにとりかかる前に、「接続」と「キュー」の区別を理解しておくことが重要です。config/queue.php
設定ファイルの中には、connections
設定オプションがあります。このオプションはAmazon SQS、Beanstalk、Redisなどのバックエンドサービスへの個々の接続を定義します。しかし、どんな指定されたキュー接続も、複数の「キュー」を持つことができます。「キュー」とはキュー済みのジョブのスタック、もしくは積み重ねのことです。Before getting started with Laravel queues, it is important to understand the distinction between "connections" and "queues". In your config/queue.php
configuration file, there is a connections
configuration option. This option defines a particular connection to a backend service such as Amazon SQS, Beanstalk, or Redis. However, any given queue connection may have multiple "queues" which may be thought of as different stacks or piles of queued jobs.
queue
接続ファイルのqueue
属性を含んでいる、各接続設定例に注目してください。ジョブがディスパッチされ、指定された接続へ送られた時にのデフォルトキューです。言い換えれば、どのキューへディスパッチするのか明確に定義していないジョブをディスパッチすると、そのジョブは接続設定のqueue
属性で定義したキューへ送られます。Note that each connection configuration example in the queue
configuration file contains a queue
attribute. This is the default queue that jobs will be dispatched to when they are sent to a given connection. In other words, if you dispatch a job without explicitly defining which queue it should be dispatched to, the job will be placed on the queue that is defined in the queue
attribute of the connection configuration:
// このジョブはデフォルトキューへ送られる
dispatch(new Job);
// このジョブは"emails"キューへ送られる
dispatch((new Job)->onQueue('emails'));
あるアプリケーションでは複数のキューへジョブを送る必要はなく、代わりに1つのシンプルなキューが適しているでしょう。しかし、複数のキューへジョブを送ることは、優先順位づけしたい、もしくはジョブの処理を分割したいアプリケーションでは、特に便利です。Laravelのキューワーカはプライオリティによりどのキューで処理するかを指定できるからです。たとえば、ジョブをhigh
キューへ送れば、より高い処理プライオリティのワーカを実行できます。Some applications may not need to ever push jobs onto multiple queues, instead preferring to have one simple queue. However, pushing jobs to multiple queues can be especially useful for applications that wish to prioritize or segment how jobs are processed, since the Laravel queue worker allows you to specify which queues it should process by priority. For example, if you push jobs to a high
queue, you may run a worker that gives them higher processing priority:
php artisan queue:work --queue=high,default
ドライバ毎の必要要件Driver Prerequisites
データベースDatabase
database
キュードライバを使用するには、ジョブを記録するためのデータベーステーブルが必要です。このテーブルを作成するマイグレーションはqueue:table
Artisanコマンドにより生成できます。マイグレーションが生成されたら、migrate
コマンドでデータベースをマイグレートしてください。In order to use the database
queue driver, you will need a database table to hold the jobs. To generate a migration that creates this table, run the queue:table
Artisan command. Once the migration has been created, you may migrate your database using the migrate
command:
php artisan queue:table
php artisan migrate
RedisRedis
redis
キュードライバーを使用するには、config/database.php
設定ファイルでRedisのデータベースを設定する必要があります。In order to use the redis
queue driver, you should configure a Redis database connection in your config/database.php
configuration file.
Redisキュー接続でRedisクラスタを使用している場合は、キュー名にキーハッシュタグを含める必要があります。これはキューに指定した全Redisキーが同じハッシュスロットに確実に置かれるようにするためです。If your Redis queue connection uses a Redis Cluster, your queue names must contain a key hash tag[https://redis.io/topics/cluster-spec#keys-hash-tags]. This is required in order to ensure all of the Redis keys for a given queue are placed into the same hash slot:
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => '{default}',
'retry_after' => 90,
],
他のドライバの要件Other Driver Prerequisites
以下の依存パッケージがリストしたキュードライバを使用するために必要です。The following dependencies are needed for the listed queue drivers:
ジョブの作成Creating Jobs
ジョブクラスの生成Generating Job Classes
キュー投入可能なアプリケーションの全ジョブは、デフォルトでapp/Jobs
ディレクトリへ保存されます。app/Jobs
ディレクトリが存在しなくても、make:job
Artisanコマンドの実行時に生成されます。新しいキュージョブをArtisan CLIで生成できます。By default, all of the queueable jobs for your application are stored in the app/Jobs
directory. If the app/Jobs
directory doesn't exist, it will be created when you run the make:job
Artisan command. You may generate a new queued job using the Artisan CLI:
php artisan make:job SendReminderEmail
非同期で実行するため、ジョブをキューへ投入することをLaravelへ知らせる、Illuminate\Contracts\Queue\ShouldQueue
インターフェイスが生成されたクラスには実装されます。The generated class will implement the Illuminate\Contracts\Queue\ShouldQueue
interface, indicating to Laravel that the job should be pushed onto the queue to run asynchronously.
クラス構成Class Structure
ジョブクラスは通常とてもシンプルで、キューによりジョブが処理される時に呼び出される、handle
メソッドのみで構成されています。手始めに、ジョブクラスのサンプルを見てみましょう。この例は、ポッドキャストの公開サービスを管理し、公開前にアップロードしたポッドキャストファイルを処理する必要があるという仮定です。Job classes are very simple, normally containing only a handle
method which is called when the job is processed by the queue. To get started, let's take a look at an example job class. In this example, we'll pretend we manage a podcast publishing service and need to process the uploaded podcast files before they are published:
<?php
namespace App\Jobs;
use App\Podcast;
use App\AudioProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class ProcessPodcast implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
protected $podcast;
/**
* 新しいジョブインスタンスの生成
*
* @param Podcast $podcast
* @return void
*/
public function __construct(Podcast $podcast)
{
$this->podcast = $podcast;
}
/**
* ジョブの実行
*
* @param AudioProcessor $processor
* @return void
*/
public function handle(AudioProcessor $processor)
{
// アップロード済みポッドキャストの処理…
}
}
この例中、キュージョブのコンテナーに直接Eloquentモデルが渡せることに注目してください。ジョブが使用しているSerializesModels
トレイトによりEloquentモデルは優雅にシリアライズされ、ジョブが処理される時にアンシリアライズされます。キュー投入されたジョブがコンテナでEloquentモデルを受け取ると、モデルの識別子のみシリアライズされています。ジョブが実際に処理される時、キューシステムは自動的にデータベースから完全なモデルインスタンスを再取得します。これらは全てアプリケーションの完全な透過性のためであり、Eloquentモデルインスタンスをシリアライズするときに発生する問題を防ぐことができます。In this example, note that we were able to pass an Eloquent model[/docs/{{version}}/eloquent] directly into the queued job's constructor. Because of the SerializesModels
trait that the job is using, Eloquent models will be gracefully serialized and unserialized when the job is processing. If your queued job accepts an Eloquent model in its constructor, only the identifier for the model will be serialized onto the queue. When the job is actually handled, the queue system will automatically re-retrieve the full model instance from the database. It's all totally transparent to your application and prevents issues that can arise from serializing full Eloquent model instances.
handle
メソッドはキューによりジョブが処理されるときに呼びだされます。ジョブのhandle
メソッドにタイプヒントにより依存を指定できることに注目してください。Laravelのサービスコンテナが自動的に依存を注入します。The handle
method is called when the job is processed by the queue. Note that we are able to type-hint dependencies on the handle
method of the job. The Laravel service container[/docs/{{version}}/container] automatically injects these dependencies.
Note:
Rawイメージコンテンツのようなバイナリデータは、キュージョブへ渡す前に、base64_encode
関数を通してください。そうしないと、そのジョブはキューへ設置する前にJSONへ正しくシリアライズされません。{note} Binary data, such as raw image contents, should be passed through thebase64_encode
function before being passed to a queued job. Otherwise, the job may not properly serialize to JSON when being placed on the queue.
ジョブのディスパッチDispatching Jobs
ジョブクラスが書き上がったら、dispatch
ヘルパによりディスパッチできます。dispatch
ヘルパは引数がひとつだけ必要で、ジョブインスタンスです。Once you have written your job class, you may dispatch it using the dispatch
helper. The only argument you need to pass to the dispatch
helper is an instance of the job:
<?php
namespace App\Http\Controllers;
use App\Jobs\ProcessPodcast;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PodcastController extends Controller
{
/**
* 新ポッドキャストの保存
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// ポッドキャスト作成…
dispatch(new ProcessPodcast($podcast));
}
}
">Tip!!
dispatch
ヘルパは短くてグローバルに使用できる関数の利便性を提供しており、同時にテストもとても簡単にできます。Laravelのテストに関するドキュメントで詳細を学んでください。{tip} Thedispatch
helper provides the convenience of a short, globally available function, while also being extremely easy to test. Check out the Laravel testing documentation[/docs/{{version}}/testing] to learn more.
遅延ディスパッチDelayed Dispatching
キューされたジョブの実行を遅らせたい場合は、ジョブインスタンスに対しdelay
メソッドを使用してください。delay
メソッドは、生成したジョブクラスにデフォルトで含まれている、Illuminate\Bus\Queueable
トレイトにより提供されています。例として、ディスパッチされた10分後まで、ジョブの処理を遅らせる指定をしてみましょう。If you would like to delay the execution of a queued job, you may use the delay
method on your job instance. The delay
method is provided by the Illuminate\Bus\Queueable
trait, which is included by default on all generated job classes. For example, let's specify that a job should not be available for processing until 10 minutes after it has been dispatched:
<?php
namespace App\Http\Controllers;
use Carbon\Carbon;
use App\Jobs\ProcessPodcast;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PodcastController extends Controller
{
/**
* 新しいポッドキャストの保存
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// ポッドキャストの作成…
$job = (new ProcessPodcast($podcast))
->delay(Carbon::now()->addMinutes(10));
dispatch($job);
}
}
Note: {note} The Amazon SQS queue service has a maximum delay time of 15 minutes.
Amazon SQSキューサービスは、最大15分の遅延時間です。
キューと接続のカスタマイズCustomizing The Queue & Connection
特定キューへのディスパッチDispatching To A Particular Queue
別のキューへジョブを投入することで、キュージョブを「カテゴライズ」でき、数々のキューにいくつのワーカを割り付けるかでプライオリティ付もできます。これはキュー設定ファイルで定義した、別のキュー「接続」へジョブを投入することではなく、一つの接続の指定したキューへ投入することです。キューを指定するには、ジョブインスタンスのonQueue
メソッドを使ってください。By pushing jobs to different queues, you may "categorize" your queued jobs and even prioritize how many workers you assign to various queues. Keep in mind, this does not push jobs to different queue "connections" as defined by your queue configuration file, but only to specific queues within a single connection. To specify the queue, use the onQueue
method on the job instance:
<?php
namespace App\Http\Controllers;
use App\Jobs\ProcessPodcast;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PodcastController extends Controller
{
/**
* 新しいポッドキャストの保存
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// ポッドキャストの作成…
$job = (new ProcessPodcast($podcast))->onQueue('processing');
dispatch($job);
}
}
特定の接続へのディスパッチDispatching To A Particular Connection
複数キューの接続を取り扱う場合、どの接続へジョブを投入するか指定できます。接続を指定するには、ジョブインスタンスのonConnection
メソッドを利用します。If you are working with multiple queue connections, you may specify which connection to push a job to. To specify the connection, use the onConnection
method on the job instance:
<?php
namespace App\Http\Controllers;
use App\Jobs\ProcessPodcast;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PodcastController extends Controller
{
/**
* 新しいポッドキャストの保存
*
* @param Request $request
* @return Response
*/
public function store(Request $request)
{
// ポッドキャストの作成…
$job = (new ProcessPodcast($podcast))->onConnection('sqs');
dispatch($job);
}
}
もちろん、ジョブを投入する接続とキューを指定するために、onConnection
とonQueue
メソッドをチェーンすることもできます。Of course, you may chain the onConnection
and onQueue
methods to specify the connection and the queue for a job:
$job = (new ProcessPodcast($podcast))
->onConnection('sqs')
->onQueue('processing');
エラー処理Error Handling
ジョブの処理中に例外が投げられると、そのジョブは再実行のために自動的にキューへ戻されます。そのジョブはアプリケーションで定義されている最大試行回数に達するまで、持続的に実行されます。最大試行回数はqueue:work
Artisanコマンドの--tries
スイッチにより定義されます。キューワーカの実行についての詳細情報は、この後に説明します。If an exception is thrown while the job is being processed, the job will automatically be released back onto the queue so it may be attempted again. The job will continue to be released until it has been attempted the maximum number of times allowed by your application. The number of maximum attempts is defined by the --tries
switch used on the queue:work
Artisan command. More information on running the queue worker can be found below[#running-the-queue-worker].
キューワーカの実行Running The Queue Worker
Laravelには、キューに投入された新しいジョブを処理する、キューワーカも含まれています。queue:work
Artisanコマンドを使いワーカを実行できます。queue:work
コマンドが起動したら、皆さんが停止するか、ターミナルを閉じるまで実行指示付けることに注意してください。Laravel includes a queue worker that will process new jobs as they are pushed onto the queue. You may run the worker using the queue:work
Artisan command. Note that once the queue:work
command has started, it will continue to run until it is manually stopped or you close your terminal:
php artisan queue:work
">Tip!! バックグランドで
queue:work
プロセスを永続的に実行し続けるには、キューワーカが止まらずに実行し続けていることを確実にするため、Supervisorのようなプロセスモニタを利用する必要があります。{tip} To keep thequeue:work
process running permanently in the background, you should use a process monitor such as Supervisor[#supervisor-configuration] to ensure that the queue worker does not stop running.
キューワーカは長時間起動するプロセスで、起動した状態のままメモリに保存されることを覚えておいてください。その結果、一度起動したら、コードベースの変更は反映されません。そのため、開発期間中はキューワーカを再起動することを忘れないでください。Remember, queue workers are long-lived processes and store the booted application state in memory. As a result, they will not notice changes in your code base after they have been started. So, during your deployment process, be sure to restart your queue workers[#queue-workers-and-deployment].
接続とキューの指定Specifying The Connection & Queue
どのキュー接続をワーカが使用するのかを指定できます。work
コマンドで指定する接続名は、config/queue.php
設定ファイルで定義されている接続と対応します。You may also specify which queue connection the worker should utilize. The connection name passed to the work
command should correspond to one of the connections defined in your config/queue.php
configuration file:
php artisan queue:work redis
指定した接続の特定のキューだけを処理するように、さらにキューワーカをカスタマイズすることもできます。たとえば、メールの処理をすべて、redis
キュー接続のemails
キューで処理する場合、以下のコマンドで単一のキューの処理だけを行うワーカを起動できます。You may customize your queue worker even further by only processing particular queues for a given connection. For example, if all of your emails are processed in an emails
queue on your redis
queue connection, you may issue the following command to start a worker that only processes only that queue:
php artisan queue:work redis --queue=emails
リソースの考察Resource Considerations
デーモンキューワーカは各ジョブを処理する前に、フレームワークを「再起動」しません。そのため、各ジョブが終了したら、大きなリソースを開放してください。たとえば、GDライブラリでイメージ処理を行ったら、終了前にimagedestroy
により、メモリを開放してください。Daemon queue workers do not "reboot" the framework before processing each job. Therefore, you should free any heavy resources after each job completes. For example, if you are doing image manipulation with the GD library, you should free the memory with imagedestroy
when you are done.
キュープライオリティQueue Priorities
時々、キューをどのように処理するかをプライオリティ付けしたいことも起きます。たとえば、config/queue.php
でredis
接続のデフォルトqueue
をlow
に設定したとしましょう。しかし、あるジョブをhigh
プライオリティでキューへ投入したい場合です。Sometimes you may wish to prioritize how your queues are processed. For example, in your config/queue.php
you may set the default queue
for your redis
connection to low
. However, occasionally you may wish to push a job to a high
priority queue like so:
dispatch((new Job)->onQueue('high'));
low
キュー上のジョブの処理が継続される前に、全high
キュージョブが処理されることを確実にするには、work
コマンドのキュー名にコンマ区切りのリストで指定してください。To start a worker that verifies that all of the high
queue jobs are processed before continuing to any jobs on the low
queue, pass a comma-delimited list of queue names to the work
command:
php artisan queue:work --queue=high,low
キューワーカとデプロイQueue Workers & Deployment
キューワーカは長時間起動プロセスであるため、リスタートしない限りコードの変更を反映しません。ですから、キューワーカを使用しているアプリケーションをデプロイする一番シンプルな方法は、デプロイ処理の間、ワーカをリスタートすることです。queue:restart
コマンドを実行することで、全ワーカを穏やかに再起動できます。Since queue workers are long-lived processes, they will not pick up changes to your code without being restarted. So, the simplest way to deploy an application using queue workers is to restart the workers during your deployment process. You may gracefully restart all of the workers by issuing the queue:restart
command:
php artisan queue:restart
このコマンドは存在しているジョブが失われないように、現在のジョブの処理が終了した後に、全キューワーカーへ穏やかに「終了する(die)」よう指示します。キューワーカはqueue:restart
コマンドが実行されると、終了するわけですから、キュージョブを自動的に再起動する、Supervisorのようなプロセスマネージャーを実行すべきでしょう。This command will instruct all queue workers to gracefully "die" after they finish processing their current job so that no existing jobs are lost. Since the queue workers will die when the queue:restart
command is executed, you should be running a process manager such as Supervisor[#supervisor-configuration] to automatically restart the queue workers.
ジョブの期限切れとタイムアウトJob Expirations & Timeouts
ジョブの有効期限Job Expiration
config/queue.php
設定ファイルの中で、各キュ接続はretry_after
オプションを定義しています。このオプションはジョブの処理を再試行するまで、キュー接続を何秒待つかを指定します。たとえば、retry_after
の値が90
であれば、そのジョブは処理が終わってから90秒の間に削除されなければ、キューへ再投入されます。通常、retry_after
値はジョブが処理を妥当に完了するまでの秒数の最大値を指定します。In your config/queue.php
configuration file, each queue connection defines a retry_after
option. This option specifies how many seconds the queue connection should wait before retrying a job that is being processed. For example, if the value of retry_after
is set to 90
, the job will be released back onto the queue if it has been processing for 90 seconds without being deleted. Typically, you should set the retry_after
value to the maximum number of seconds your jobs should reasonably take to complete processing.
Note:
retry_after
を含まない唯一の接続は、Amazon SQSです。SQSはAWSコンソールで管理する、Default Visibility Timeoutを元にリトライを行います。{note} The only queue connection which does not contain aretry_after
value is Amazon SQS. SQS will retry the job based on the Default Visibility Timeout[https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/AboutVT.html] which is managed within the AWS console.
ワーカタイムアウトWorker Timeouts
queue:work
Artisanコマンドは--timeout
オプションも提供しています。--timeout
オプションはLaravelキューマスタプロセスが、ジョブを処理する子のキューワーカをKillするまでどのくらい待つかを指定します。外部のHTTP呼び出しの反応が無いなど様々な理由で、時より子のキュープロセスは「フリーズ」します。--timeout
オプションは指定した実行時間を過ぎた、フリーズプロセスを取り除きます。The queue:work
Artisan command exposes a --timeout
option. The --timeout
option specifies how long the Laravel queue master process will wait before killing off a child queue worker that is processing a job. Sometimes a child queue process can become "frozen" for various reasons, such as an external HTTP call that is not responding. The --timeout
option removes frozen processes that have exceeded that specified time limit:
php artisan queue:work --timeout=60
retry_after
設定オプションと--timeout
CLIオプションは異なります。しかし、確実にジョブを失わずに、一度だけ処理を完了できるよう共に働きます。The retry_after
configuration option and the --timeout
CLI option are different, but work together to ensure that jobs are not lost and that jobs are only successfully processed once.
Note:
--timeout
値は、最低でも数秒retry_after
設定値よりも短くしてください。これにより、与えられたジョブを処理するワーカが、ジョブのリトライ前に確実にkillされます。--timeout
オプションをretry_after
設定値よりも長くすると、ジョブが2度実行されるでしょう。{note} The--timeout
value should always be at least several seconds shorter than yourretry_after
configuration value. This will ensure that a worker processing a given job is always killed before the job is retried. If your--timeout
option is longer than yourretry_after
configuration value, your jobs may be processed twice.
ワーカスリープ時間Worker Sleep Duration
ジョブがキュー上に存在しているとき、ワーカは各ジョブ間にディレイを取らずに実行し続けます。sleep
オプションは新しく処理するジョブが存在しない時に、どの程度「スリープ」するかを決めます。When jobs are available on the queue, the worker will keep processing jobs with no delay in between them. However, the sleep
option determines how long the worker will "sleep" if there are no new jobs available:
php artisan queue:work --sleep=3
Supervisor設定Supervisor Configuration
SupervisorのインストールInstalling Supervisor
SupervisorはLinuxオペレーティングシステムのプロセスモニタで、queue:work
プロセスが落ちると自動的に起動します。UbuntuにSupervisorをインストールするには、次のコマンドを使ってください。Supervisor is a process monitor for the Linux operating system, and will automatically restart your queue:work
process if it fails. To install Supervisor on Ubuntu, you may use the following command:
sudo apt-get install supervisor
Laravel Forgeの使用を考慮してください。{tip} If configuring Supervisor yourself sounds overwhelming, consider using Laravel Forge[https://forge.laravel.com], which will automatically install and configure Supervisor for your Laravel projects.
">Tip!! Supervisoの設定に圧倒されそうならば、Laravelプロジェクトのために、Supervisorを自動的にインストールし、設定する
Supervisorの設定Configuring Supervisor
Supervisorの設定ファイルは、通常/etc/supervisor/conf.d
ディレクトリに保存します。このディレクトリの中には、Supervisorにどのようにプロセスを監視するのか指示する設定ファイルを好きなだけ設置できます。たとえば、laravel-worker.conf
ファイルを作成し、queue:work
プロセスを起動、監視させてみましょう。Supervisor configuration files are typically stored in the /etc/supervisor/conf.d
directory. Within this directory, you may create any number of configuration files that instruct supervisor how your processes should be monitored. For example, let's create a laravel-worker.conf
file that starts and monitors a queue:work
process:
[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/forge/app.com/artisan queue:work sqs --sleep=3 --tries=3
autostart=true
autorestart=true
user=forge
numprocs=8
redirect_stderr=true
stdout_logfile=/home/forge/app.com/worker.log
この例のnumprocs
ディレクティブは、Supervisorに全部で8つのqueue:workプロセスを実行・監視し、落ちている時は自動的に再起動するように指示しています。もちろんcommand
ディレクティブのqueue:work sqs
の部分を変更し、希望のキュー接続に合わせてください。In this example, the numprocs
directive will instruct Supervisor to run 8 queue:work
processes and monitor all of them, automatically restarting them if they fail. Of course, you should change the queue:work sqs
portion of the command
directive to reflect your desired queue connection.
Supervisorの起動Starting Supervisor
設定ファイルができたら、Supervisorの設定を更新し起動するために以下のコマンドを実行してください。Once the configuration file has been created, you may update the Supervisor configuration and start the processes using the following commands:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*
Supervisorの詳細情報は、Supervisorドキュメントで確認してください。For more information on Supervisor, consult the Supervisor documentation[http://supervisord.org/index.html].
失敗したジョブの処理Dealing With Failed Jobs
時より、キューされたジョブは失敗します。心配ありません。物事は計画通りに進まないものです。Laravelではジョブを再試行する最大回数を指定できます。この回数試行すると、そのジョブはfailed_jobs
データベーステーブルに挿入されます。failed_jobs
テーブルのマイグレーションを生成するにはqueue:failed-table
コマンドを実行して下さい。Sometimes your queued jobs will fail. Don't worry, things don't always go as planned! Laravel includes a convenient way to specify the maximum number of times a job should be attempted. After a job has exceeded this amount of attempts, it will be inserted into the failed_jobs
database table. To create a migration for the failed_jobs
table, you may use the queue:failed-table
command:
php artisan queue:failed-table
php artisan migrate
次にキューワーカの実行時、queue:work
コマンドに--tries
スイッチを付け、最大試行回数を指定します。--tries
オプションに値を指定しないと、ジョブは無限に試行します。Then, when running your queue worker[#running-the-queue-worker], you should specify the maximum number of times a job should be attempted using the --tries
switch on the queue:work
command. If you do not specify a value for the --tries
option, jobs will be attempted indefinitely:
php artisan queue:work redis --tries=3
ジョブ失敗後のクリーンアップCleaning Up After Failed Jobs
失敗時にジョブ特定のクリーンアップを実行するため、ジョブクラスでfailed
メソッドを直接定義できます。これはユーザに警告を送ったり、ジョブの実行アクションを巻き戻すために最適な場所です。failed
メソッドには、そのジョブを落とすことになった例外(Exception
)が渡されます。You may define a failed
method directly on your job class, allowing you to perform job specific clean-up when a failure occurs. This is the perfect location to send an alert to your users or revert any actions performed by the job. The Exception
that caused the job to fail will be passed to the failed
method:
<?php
namespace App\Jobs;
use Exception;
use App\Podcast;
use App\AudioProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class ProcessPodcast implements ShouldQueue
{
use InteractsWithQueue, Queueable, SerializesModels;
protected $podcast;
/**
* 新しいジョブインスタンスの生成
*
* @param Podcast $podcast
* @return void
*/
public function __construct(Podcast $podcast)
{
$this->podcast = $podcast;
}
/**
* ジョブの実行
*
* @param AudioProcessor $processor
* @return void
*/
public function handle(AudioProcessor $processor)
{
// アップロード済みポッドキャストの処理…
}
/**
* 失敗したジョブの処理
*
* @param Exception $exception
* @return void
*/
public function failed(Exception $exception)
{
// 失敗の通知をユーザへ送るなど…
}
}
ジョブ失敗イベントFailed Job Events
ジョブが失敗した時に呼び出されるイベントを登録したい場合、Queue::failing
メソッドが使えます。このイベントはメールやHipChatにより、チームへ通知する良い機会になります。例として、Laravelに含まれているAppServiceProvider
で、このイベントのコールバックを付け加えてみましょう。If you would like to register an event that will be called when a job fails, you may use the Queue::failing
method. This event is a great opportunity to notify your team via email or HipChat[https://www.hipchat.com]. For example, we may attach a callback to this event from the AppServiceProvider
that is included with Laravel:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Queue;
use Illuminate\Queue\Events\JobFailed;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* 全アプリケーションサービスの初期処理
*
* @return void
*/
public function boot()
{
Queue::failing(function (JobFailed $event) {
// $event->connectionName
// $event->job
// $event->exception
});
}
/**
* サービスプロバイダの登録
*
* @return void
*/
public function register()
{
//
}
}
失敗したジョブの再試行Retrying Failed Jobs
failed_jobs
データベーステーブルに挿入された、失敗したジョブを全部確認したい場合はqueue:failed
Arisanコマンドを利用します。To view all of your failed jobs that have been inserted into your failed_jobs
database table, you may use the queue:failed
Artisan command:
php artisan queue:failed
queue:failed
コマンドはジョブID、接続、キュー、失敗した時間をリスト表示します。失敗したジョブをジョブIDで指定することでリトライできます。たとえば、IDが5
の失敗したジョブを再試行するため、以下のコマンドを実行します。The queue:failed
command will list the job ID, connection, queue, and failure time. The job ID may be used to retry the failed job. For instance, to retry a failed job that has an ID of 5
, issue the following command:
php artisan queue:retry 5
失敗したジョブをすべて再試行するには、IDとしてall
をqueue:retry
コマンドへ指定し、実行してください。To retry all of your failed jobs, execute the queue:retry
command and pass all
as the ID:
php artisan queue:retry all
失敗したジョブを削除する場合は、queue:forget
コマンドを使います。If you would like to delete a failed job, you may use the queue:forget
command:
php artisan queue:forget 5
失敗したジョブを全部削除するには、queue:flush
コマンドを使います。To delete all of your failed jobs, you may use the queue:flush
command:
php artisan queue:flush
ジョブイベントJob Events
Queue
ファサードにbefore
とafter
メソッドを使い、キューされたジョブの実行前後に実行する、コールバックを指定できます。これらのコールバックはログを追加したり、ダッシュボードの状態を増加させたりするための機会を与えます。通常、これらのメソッドはサービスプロバイダから呼び出します。たとえば、Laravelに含まれるAppServiceProvider
を使っていましょう。Using the before
and after
methods on the Queue
facade[/docs/{{version}}/facades], you may specify callbacks to be executed before or after a queued job is processed. These callbacks are a great opportunity to perform additional logging or increment statistics for a dashboard. Typically, you should call these methods from a service provider[/docs/{{version}}/providers]. For example, we may use the AppServiceProvider
that is included with Laravel:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Queue;
use Illuminate\Support\ServiceProvider;
use Illuminate\Queue\Events\JobProcessed;
use Illuminate\Queue\Events\JobProcessing;
class AppServiceProvider extends ServiceProvider
{
/**
* 全アプリケーションサービスの初期処理
*
* @return void
*/
public function boot()
{
Queue::before(function (JobProcessing $event) {
// $event->connectionName
// $event->job
// $event->job->payload()
});
Queue::after(function (JobProcessed $event) {
// $event->connectionName
// $event->job
// $event->job->payload()
});
}
/**
* サービスプロバイダの登録
*
* @return void
*/
public function register()
{
//
}
}
Queue
ファサードのlooping
メソッドを使用し、ワーカがキューからジョブをフェッチする前に、指定したコールバックを実行できます。たとえば、直前の失敗したジョブの未処理のままのトランザクションをロールバックするクロージャを登録できます。Using the looping
method on the Queue
facade[/docs/{{version}}/facades], you may specify callbacks that execute before the worker attempts to fetch a job from a queue. For example, you might register a Closure to rollback any transactions that were left open by a previously failed job:
Queue::looping(function () {
while (DB::transactionLevel() > 0) {
DB::rollBack();
}
});