LaravelでQueueとJobを使ってみる基礎基礎メモ
キューを利用することで、一部の処理を非同期で実行することができます。 以下はユーザー登録する場合にキューを利用した場合のイメージです。
キューを利用することで、メール送信を待たずに、完了画面を表示することができます。
非同期処理をする
Queueサービス
LaravelにはQueueサービスという非同期を簡単に行うためのサービスが用意されています。
データベースや、Beanstalkd(AWS Elastic Beanstalkとは関係ない)、Amazon SQS、Redisなどにジョブ(非同期処理)を溜め込んでいきます。
登録されたジョブは、基本的には登録順番に実行されます。
実行されるとドライバー(データベースなど)から削除されます。
Queue用のデータベースを用意する
LaravelではartisanコマンドでQueue用のテーブルを作成することができます。
php artisan queue:table php artisan migrate
jobs
、failed_jobs
の2つのテーブルが追加されます。
次に.env
を修正します。
QUEUE_CONNECTION=sync ↓ QUEUE_CONNECTION=database
.env
に追加。
QUEUE_DRIVER=database
非同期でメールを送信してみる
メールの送信方法は割愛します。
簡単ですが、MailHogを利用してメールを送信する為の メモはこちらにあります。
まずはジョブを作成します。
php artisan make:job SendMail
/app/Jobs
配下にファイルが作成されます。
ファイルの中身は以下です。
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; class SendMail implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Create a new job instance. * * @return void */ public function __construct() { // } /** * Execute the job. * * @return void */ public function handle() { // } }
handle
メソッドがジョブの実行処理です。
handle
に処理を追加していきます。
※Mailファザードを読み込むのを忘れないように
public function handle() { Mail::to('sample@example.com')->send(new SampleMail()); }
メール送信用のコントローラーを作成して、 controllerをにメール送信処理を追加します。
まずコントローラーを作成します。
php artisan make:controller MailController
コントローラーに処理を追加します。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Jobs\SendMail; class MailController extends Controller { // public function create(){ SendMail::dispatch(); return '送信完了'; } }
DBのjobsテーブルを確認するとjobが設定されています。
このままだと、jobは実行されません。
jobを実行するにはjobを実行するプロセスのWorkerが必要になります。
以下のコマンドでWorkerを起動します。
docker exec -it laradock_workspace_1 /bin/bash php artisan queue:work // workerを実行
Workerを起動すると、キューにあるjobが実行されます。
[2019-12-21 01:05:21][42] Processing: App\Jobs\SendMail [2019-12-21 01:05:22][42] Processed: App\Jobs\SendMail
失敗した場合は、以下のように表示されます。
[2019-12-21 00:52:36][37] Processing: App\Jobs\SendMail [2019-12-21 00:52:36][37] Failed: App\Jobs\SendMail
ジョブの実行ログは/storage/logs
で確認できます。
jobが完了するとメールが送信されたのを確認できます。
その他
Jobの実行を遅らせる
delay(日時)
でjobを遅延実行することができます。
class MailController extends Controller { public function create(){ SendMail::dispatch()->delay(now()->addMinutes(5)); return '送信完了'; } }
Jobを1つだけ実行する
--once
オプションをつけてworkerを起動すると、Queueuに溜まっているJobを1つだけ実行します。
php artisan queue:work --once
溜まっているJobをすべて実行する
delayの実行時間になっていないJobを除いて、Queueに溜まっているJobをすべて実行します。
php artisan queue:work --stop-when-empty
queueの名前を指定して実行する
負荷分散などの為、キュー分けて実行するなどに利用します。
php artisan queue:work --queue=名前
名前の付け方はdispatchのonQueue
メソッドで以下のように指定します。
class MailController extends Controller { public function create(){ SendMail::dispatch()->onQueue('hogehoge'); return '送信完了'; } }
テーブルに追加されたJobには以下のように設定した名前が付きます。
なにも指定しなければdefaultになります。
同じqueue名のJobをすべて実行する場合は、こんな感じ。
php artisan queue:work --stop-when-empty --queue=hogehoge