JobとQueueも設定はこんなに簡単LaravelではJob(ジョブ)もQueue(キュー)も使用しなくてもアプリケーションの構築を行うことができるので、設定したこともなければ存在さえしらない人が多いかもしれません。本文書では入門者でもわかるようにJobの作成方法からQueueの使い方まで簡単なコードを使って説明を行っていきます。これまで使ったことがない人もぜひこの機会にQueueにチェレンジしてください。キューは処理が実行されるのを待っているジョブのリストです。これだけでは難しいと思うので、コンビニを例にして説明します。コンビニでは昼時になるとレジの前にたくさんの人がレジ待ちしていると思います。この列がキューを意味し、レジで行うお客様の会計処理1つ1つがジョブになります。キューとジョブは身近なところに存在するのでイメージすることは簡単です。後ほどWorker(ワーカー)という単語がでてきますが、会計のジョブを処理する店員がワーカーに対応します。同期と非同期キューを利用するためには、同期処理と非同期処理という言葉を理解しておく必要があります。最近頻繁に街中で見かけるUberEatsを例に考えてみましょう。お客様がスマホを通して注文を行います。注文を受け取った店は料理の調理を開始します。それと同時にUberEatsからお店の近くの配達員に連絡が入り、配達を行いたい配達員が決定され、お店に料理を取りに行きます。その後配達員がお店で料理を受け取ってお客様の元に料理を運びます。これが同期処理で行われていると店が注文を受け取ってもすぐにUberEatsの配達員には連絡は行われません。配達員への連絡はお店の料理ができあがるまで待つ必要があります。料理ができあがったらUberEatsから配達員に連絡が入り、配達員が決定した後配達員はお店に料理を取りに向かいします。お店は配達員が料理をお客様の元に届けるまで次の注文を受け取らず待ちます。配達員がお客様に届けた連絡を受けて次の注文を受けます。通常は非同期に処理が行われているので、お店に注文が入ると料理が出来上がるのを待たず、配達員に連絡が入り、調理中に配達員がお店に向かいます。お店は料理ができたら、次の注文の料理を開始します。同期と非同期はお客様、お店にとってどちらがいいでしょうか?非同期だと思います。このように非同期処理をうまく活用することで効率よく処理を行うことができます。この例でのキューは店にとっては注文です。一人しか料理人がいない場合は順番にキューに入った処理を行なっていかなければなりません。ジョブは注文を受けたメニューになります。UberEatsの仕組みは細かくはわかりませんが、配達員の場合は、1件配送依頼の処理が完了したら、また次の1件の配送依頼を受けるのであればキューはなく同期処理を行なっていることになります。環境構築ジョブとキューの動作確認を行うためには、Laravel環境の構築を行う必要があります。環境構築については簡単に手順を説明していきます。Laravelのインストールと設定composerコマンドでLaravelのインストールを行います。データベースにはsqliteを利用します。touchコマンドでデータベースファイルを作成します。コマンドはLaravelのインストールディレクトリjob_queueの下で実行します。database/database.sqlite.envファイルでデータベースの設定をmysqlからsqliteに変更します。MySQLよりもSQLiteのほうが設定が簡単なのでSQLiteを使用しています。MySQLでも問題ありません。DB_CONNECTION=sqlite.envファイルのDB_CONNECTION以外のデータベースに関わる設定は削除します。ユーザ登録のための認証機能を使用するため、認証機能の追加を行います。migrateコマンドでテーブルの作成を行います。password_resetsテーブルが作成されます。seconds)メール送信のSMTP設定ジョブとキューの動作確認を行う際にメール送信を行うので、メール設定を行います。ここではダミーのSMTPサーバのmailtrapを利用します。.envファイルを開いてmailTrapの接続情報を設定します。各環境による異なるMAIL_FROM_ADDRESS=from@example.comMAIL_FROM_NAME=Exampleあわせて読みたいMailTrapのダミーのSMTPサーバ使ってテストメール送信SMTPサーバが準備できない場合はMAIL_DRIVERにlogを設定してください。送信したメールの内容がログファイルに書き込まれます。ログファイルはstorage/logsの下に作成されます。serveで開発用WEBサーバを起動し、ユーザ登録画面が表示されるか確認を行なってください。今後はこの画面からユーザ登録を行い、キューを使用する場合としない場合の比較を行なっていきます。ユーザ登録画面ここまでの作業でジョブ、キューの動作確認を行うためのLaravelの環境設定は完了です。キューを使用しない場合キューを使用せずユーザ登録後にWelocomeメールを送信するコードを記述します。ユーザ登録の処理はApp¥Http¥Controllers¥Auth¥RegisterController.phpファイル内のcreateメソッドで行われているため、createメソッドの中に登録後の処理を記述します。$userでユーザ情報を戻しています。送信するメールの内容を記述するためにMailableクラスのWelcomeMailを作成します。successfully.実行後、app¥Mailディレクトリの下にWelcomeMail.phpが作成されます。WelcomeMail.phpのbuildメソッドを下記のように書き換えます。viewメソッドで指定したemails.welcomeファイルにはメールの内容を記述します。subjectメソッドはメールのタイトルを入力します。mail');}resource¥viewsディレクトリの下にemails¥welcome.blade.phpファイルを作成します。welcome.blade.phpファイルには以下を書き込みます。ユーザ登録ありがとうございます。メール送信の処理を追加App¥Http¥Controllers¥Auth¥RegisterController.phpファイル内のcreateメソッドの中にメール送信のコードを追加します。登録したユーザのメールアドレス宛にWelcomeメールを送信する処理です。WelcomeMail());}待ちの長さは環境にも依存しますがユーザがユーザ登録画面ですべての情報を入力してRegisterボタンを押してから次のページに行くまでに3-4秒間ブラウザが応答していない状態になることを必ず確認してください。この待ちがキューと関連しています。ユーザ登録画面ユーザの登録画面が完了するとメールが送信されます。mailtrapでメールを受信します。MailTrapメール受信キューを利用した場合キューの設定ファイルキューの設定は、.envファイルからconfig¥queue.phpファイルの中で行います。キューの設定についてキューを利用していない場合、ユーザ登録のRegisterボタンを押してから登録後の次の画面に行くまでに数秒かかることを確認しました。これはメールを送信する処理が終わるまで次の処理が行えず待ちが生じているためです。デフォルトではすべての処理が同期処理で行われるため、.envファイルのキューの設定を見ると同期のsynchronizeという意味を持つsyncが設定されています。“redis”などのキューが準備されています。最初にもっとも設定が簡単なdatabaseをキューに利用します。そのためQUEUE_CONNECTIONをdatabaseに変更してください。後ほど別のキューであるredisを使った場合の設定手順も確認します。キューにデータベースを利用.envファイルのQUEUE_CONNECTIONをsyncからdatabaseに変更します。キューはジョブをリスト化して保存しておく必要があるため保存場所が必要となります。設定値をdatabaseにするとキューの保存場所がデータベース内のテーブルになります。queue:tableコマンドを実行します。successfully!app¥database¥migrationsディレクトリにjobsテーブルのマイグレーションファイルが作成されます。migrateコマンドを実行するとjobsテーブルが作成されます。キューを使用するとこのjobsテーブルの中に未実行のジョブが保存されていきます。seconds)これでdatabaseキューを使う準備は完了です。ジョブの作成ジョブ単位でキューを利用するため先ほど作成したメール送信のコードをジョブとして登録します。make:jobコマンドを使用します。successfully.ジョブはapp¥Jobsディレクトリの下に作成されます。作成されたSendWelcomeMail.phpファイルは下記のようになっています。}}メール送信のコードを追加します。}}ジョブの作成は完了です。キューを使用ジョブの作成が完了したので、キューを使用します。ジョブをキューを使って実行したい場合はdispatchメソッドを使用します。dispatchメソッドを実行することでジョブはキューに送られます。RegisterController.phpの処理にジョブSendWelcomeMailを追加します。$user;}ユーザ登録を登録画面から実行するとキューを使用する前は次の画面に進むまでに数秒待つ必要がありましたがキューを使用するとすぐに次の画面に移動します。今の設定のままでは何分経過してもジョブの中で実行されているWelcomeメールが送信されず、MaiTrapのinBoxにもメールが届きません。キューを保存しているjobsテーブルを確認してみましょう。serveコマンドで開発サーバを再起動してください。.envファイルの設定変更が反映されていない可能性があります。jobsテーブルの確認GUIツールを(TablePlus)使ってjobsテーブルの中身を確認するとSendWelcomeMailのジョブが登録されていることがわかります。あわせて読みたいTablePlusをMACにインストールしMySQL,SQLite接続jobsテーブルに行が追加jobsテーブルにはキューに残っている未実行のジョブが保存されるのでSendWelcomeMailジョブが未実行のため、メールが送信されていないことがわかります。ジョブはどのタイミングで実行されるのでしょう?キューにあるジョブの実行キューの中に入っているジョブは自動で実行されるわけではなくジョブを実行する別のプロセスであるWorker(ワーカー)が必要となります。キューの中にあるジョブを実行するためには、ワーカーを起動する必要があります。queue:workコマンドを実行します。queue:work実行後、起動したワーカーによりキューに残っていたSendWelcomeMailの実行が開始(Processing)され、しばらくして処理が完了(Processed)します。完了するとMailtrapのinBoxにWelcomeメールが受信されていることを確認することができます。メール送信にlogを設定している場合はログファイルにメールに関する情報が書き込まれます。queue:workコマンドを実行し、プロセスを終了しなければワーカーは起動したままの状態となります。再度別のユーザを追加してみましょう。今度はワーカーが起動している状態なので、ユーザを登録するとすぐにWelcomeメールが送信されます。ワーカーが処理を行なったことも確認することができます。App\Jobs\SendWelcomeMailユーザ登録にキューを使用しているのでRegisrerボタンを押すとメール送信を待たず次の画面が表示されます。ワーカーがキューにジョブが入ったことを検知してジョブの処理を行います。ワーカープロセスの状態はsupervisorで監視を行うことができます。Ubutun環境でのsupervisorの設定手順については下記の文書にまとめています。あわせて読みたい【Laravel】UbuntuにSupervisorをインストールキューにredisを利用した場合キューにredisを利用する場合は、.envファイルを更新する必要があります。redisのインストールに関しては下記を参照してください。あわせて読みたいMACとUbuntuへのRedisのインストールと動作確認QUEUE_CONNECTIONをredisに変更します。REDIS_HOSTなどredisに関する設定がありますが、デフォルトのまま設定の変更を行っていなければそのままの値で変更する必要はありません。・REDIS_HOST=127.0.0.1REDIS_PASSWORD=nullREDIS_PORT=6379PredisパッケージのインストールLaravelのQueueとしてredisを使用するためには、Predisパッケージをインストールする必要があります。composerコマンドを使用してインストールを行います。エラーが発生するのでPredisパッケージを忘れずにインストールしてください。処理の実行ジョブなどの設定は何も設定変更を行わず、ユーザの登録を行います。redisに変更されたことを確認するためにワーカーを起動している場合は一度停止してください。ユーザ登録後にGUIツール(TablePlus)を使ってredisに接続し、ジョブの情報が登録されていないか確認を行います。redis上のdb0にLaravelのジョブ情報が登録されていることがわかります。Laravelのジョブの確認キュー(redis上)に登録されたジョブを実行するためにワーカーを起動します。起動と同時にジョブが実行されるのがわかります。App\Jobs\SendWelcomeMailProcessedでジョブの処理が完了していることを確認後、Mailtrapを見るとWelcomeメールが届いていることを確認することができます。ジョブの処理完了後redisに登録されたジョブもなくなります。まとめこのようにキューとジョブを利用するとことでユーザ登録時のユーザの待ちのストレスを解消することができました。キューとジョブをうまく活用することでアプリケーション中での処理待ちを減らすことができます。本文書を理解できたら下記の文書を読み進めることをおすすめしています。