お疲れ様です。ギークフィードエンジニアのサミーラです。私は2年間ぐらいLaravelフレームワークでWEBシステム開発をしています。
Laravelによるプロジェクトの経験
- 通話録音システムの制御および表示Webシステム
- モバイルゲームのバックエンドシステム
- WEB電話帳システム
- IP-PBXのWEBプロビジョニングシステム。
目次
Introduction
PHPはステートレススクリプト言語なので、リクエストを取得し、処理して、レスポンスを返すものです。ただし、長時間実行されるプロセスをバックグラウンドで実行し、ユーザーにレスポンスを早く返す必要がある場合もありますね。今回のブログでは、そういう時にLaravelで対応できる方法について話したいと思います。そのためにLaravelのQueueという機能を使用します。Laravelのqueueドライバーがいくつかありますが、このブログでLaravelのデータベースQueueを使用します。
これらはlaravelの基本的な知識で行うことができます。
バックグラウンド処理の場合はデータフロー
★まずはフロントエンド側からプロセスを開始します。
- ユーザーのアクションによって画面(ブラウザ)からコントローラーにリクエストが送って来る。
- コントローラーで
- リクエストパラメーター取得
- リクエスト処理
- 長時間の処理をJOBクラスのオブジェクトに入れる
- JOBオブジェクトをQueueに入れる
- 画面(ブラウザ)へレスポンス返す
★その後に非同期でWorkerからバックグラウンド処理を開始します。
- QueueからJOBを取得
- JOBを処理
- 処理完了後に次のJobを処理、等々
★複数のWorkerを実行することが可能なので、バックグラウンドで非同期で処理可能なプロセス数を上がって、処理がチューニングすることができます。
実装の概要
★以下の概要はLaravelのプロジェクトを作成して、データベース設定が完了している段階から説明です。
- 画面側で必要なフォーム、ボタン、etc..を開発。
- リクエスト処理用のコントローラーの開発。
- ルートを追加。
- laravel Queueを設定。
- Queueドライバー設定。
- JOBクラスの開発。(長時間の処理がこれに入れる)
- コントローラーからJOBをdispatchする。
- Workerを実行。
実装
画面側で必要なフォーム、ボタン、etc..を開発。
- <プロジェクトディレクトリ>/app/resources/views/welcome.blade.phpを作成
- 以下のソースコードをwelcome.blade.phpに入れる
1 2 3 4 5 6 7 8 9 |
<html> <body> <h1>Laravel Background Processing</h1> <form method="post" action="/process"> サンプルデータ:<input type="text" name="sample_data" /> <input type="submit" value="Submit"/> </form> </body> </html> |
リクエスト処理用のコントローラーの開発。
- コントローラーを作成
1php artisan make:controller <コントローラー名>
- 以下のソースコードをコントローラーに入れる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class ProcessController extends Controller { public function process(Request $request) { $param = $request->sample_data; //リクエストパラメーターで処理。 //例: // 1.DBアクセス、 // 2・DBインサート // 3.計算 // 4.etc.. //長い時間の処理 //例: // 1.メール送信、 // 2・音声認識 // 3.音声エンコード // 4.イメージプロセッシング // 5.etc.. return back(); } } |
ルートを追加。
- 画面側からのリクエストをコントローラーまでにルーティングするためにルートを追加する必要があります。
- <プロジェクトディレクトリ>/routes/web.phpに以下のルートを追加。
12Route::post('/<ルート名>', '<コントローラー名>@<メソッド>');例:Route::post('/process', 'ProcessController@process');
laravel Queueを設定。
- Queue用のデータベースmigrationを作成。
1php artisan queue:table
- テーブルをデータベースへmigrationする。
1php artisan migrate
Queueドライバー設定。
- LaravelのQueueでどのドライバーを使用するかどうかを「.env」ファイルで設定します。
- このブログでDatabaseのQueueドライバーを使用しますので、「.env」に以下の項目を設定する必要があります。
1QUEUE_DRIVER=database
JOBクラスの開発。(長時間の処理がこれに入れる)
- 【<プロジェクトディレクトリ>/app/Jobs/】へJobクラスを作成。
12php artisan make:job <JOBクラス名>例:php artisan make:job LongProcessJob
- 前のコントローラーに入れていた長時間処理のソースコードを以下のJOBクラスのhandle()メソッドに入れる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<?php namespace App\Jobs; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; class LongProcessJob 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() { //長い時間の処理 //例: // 1.メール送信、 // 2・音声認識 // 3.音声エンコード // 4.イメージ // 4.etc.. } } |
コントローラーからJOBをdispatchする。
- 長時間処理のソースコードをコントローラーから外して、以下のソースコードをその場所に入れる。
★delay()メソッドで、「何秒後でバックグラウンドプロセスの処理が開始されたい」という設定が必要です。この設定がないプロセスは、バックグラウンドで実行されなくなります。
1 2 3 4 5 6 |
$longJob = (new <JOBクラス名>())->delay(Carbon::now()->addSeconds(1)); dispatch($longJob); 例: $longJob = (new LongProcessJob())->delay(Carbon::now()->addSeconds(1)); dispatch($longJob); |
Workerを実行。
- 上のdispatchで長時間のJOBオブジェクトをQueueに入れます。
- QueueからJOBを取得して、処理するためにWokerを実行する必要があります。以下のコマンドでWokerを実行することができます。
1php artisan queue:work
- Workerを実行した後に新しくJOBをqueueに入ったら、自動的にworkerからJOBを実行します。
この後に参照したほうがものは。。
今の段階でLaravelを使用してPHPのバックグラウンドプロセスを実行することができます。
さらに以下の点も参照したほうがいいと思います。
- プロセス管理に複数のQueueを使用する方法。
- Queueに優先順位を付ける方法。
- JOBの最大リトライ回数、JOBのタイムアウトについて。
- LinuxのSupervisorについて。(Workerを監視するために)
LaravelのQueueでバックグラウンド処理の仕組みやメリットまとめ
ユーザーレスポンスは、ウェブシステムの大事なポイントです。長時間処理のプロセスをバックグラウンドにして、ユーザーにすぐにレスポンス返すのはいいことです。あと、複数のプロセスが非同期で実行できるので、パフォーマンスを上げることもできます。
バックグラウンド処理の仕組みとしては、JOBクラスを作成して、長時間処理のソースコードをJOBクラスに入れます。コントローラーからJOBクラスのオブジェクトをLaravelのQueueにDispatchして、すぐにユーザーへレスポンスを返すと、後でWorkerはQueueに入っているプロセスをバックグラウンドで実行します。その後は必要に合わせてQueueをチューニングすることですね。
ALL THE BEST!!! HAPPY & CLEAN CODING!!!
- SupervisorでLaravelのQueue worker管理 - 2021-07-27
- Laravelでバックグラウンド処理。。。 - 2021-03-22
- NATファイアウォール背後のサーバーをZabbixで監視するTips - 2020-09-09
- Laravelのパフォーマンスを向上しましょう - 2019-12-02
- Laravelのサービスプロバイダーの仕組みやメリットとは - 2019-09-04