テックブログ

  1. Docker
  2. 25 view

LaravelでRedisとSupervisorを導入してQueue/Jobを扱う【docker-compose】

はじめに

Laravelには、時間のかかる処理をジョブとしてキューイングしてレスポンス時間を短縮する機構が備わっています。巷ではよく databaseを用いたキューのサンプルが出回っていますが、今回紹介するのはredisを用いたキューイングです。また、supervisorを用いたプロセスモニタリングの設定も紹介します。
環境はdocker-composeで作りますので、以下の記事も合わせて参考にしてください。

ソースコード

こちらに本記事のソースコードを用意しました。

Queue(キュー)/Job(ジョブ)とは

Queue(キュー)とは日本語で列という意味で、そこにJob(ジョブ)が並んで順次実行されていきます。LaravelではJobをQueueに並ばせる処理をdispatchと呼んでいます。特に重い処理が完了するのを待たずにレスポンスを返すことでアプリケーションのレスポンス速度を高速化することができます。(処理の非同期化)

LaravelではQueueを実現するために様々なドライバーが用意されており、Database,Beanstalk、Amazon SQS、Redisなどがありますが本記事ではRedisを用いたキューイングを行なっていきます。

Laravelプロジェクトを立ち上げる

こちらにLaravelプロジェクトをdocker-composeで立ち上げるサンプルを用意しました。詳しくは下記の記事をご覧ください。

以下の手順でLaravelプロジェクトを立ち上げます。(READMEに書いてあります。)

git clone https://github.com/windii-legend/laravel-docker-compose-example.git

cd laravel-docker-compose-example

docker-compose up -d --build

docker-compose exec app bash ./docker/setup.sh

うまくいったらhttp://localhost:8000 を開いてみましょう。おなじみのLaravelの画面が表示されます!

LaravelのJobを動かす

Laravelプロジェクトが立ち上がったら早速Jobを作ります。

まず、dockerコンテナ内に入ります。

docker-compose exec app bash

cd my-laravel-app

以下のコマンドを実行してJobクラスを作成しましょう。

php artisan make:job TestJob

Job created successfully.

作成したファイルはapp/Jobs ディレクトリに保存されます。

作成されたファイルを以下のようにして、Logファイルに書き込むシンプルなジョブを定義します。

<?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;
use Illuminate\Support\Facades\Log;

class TestJob 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()
    {
        Log::info('テストJob');
    }
}


次にroutes/web.php を以下のように書き換えましょう。

use App\Jobs\TestJob;


Route::get('/', function () {
    //return view('welcome');
    $test = (new TestJob)->delay(10);
    dispatch($test);
    return 'テストJobをQueueに追加しました!';
});

http://localhost:8000にアクセスすると1Jobがdispatchされ、テストJobをQueueに追加しました! の文字列が返されます。

storage/logs 配下のログファイルに以下のようなログが書き込まれているはずです。

[2018-12-06 13:24:57] local.INFO: テストJob

Jobを10秒送らせているにも関わらず、logが即座に書き込まれます。これはあとで分かりますが、Queueにsyncを使っているからです。

RedisをQueueドライバに設定する

Redisを使うにはまずpredis/predis パッケージをComposerでインストールする必要があります。

docker-compose exec app bash

cd my-laravel-app

composer require predis/predis

docker-compose.yml にRedisを追加します。

redis:
    image: redis:5.0
    ports:
      - "6379:6379"

追加したら以下のコマンドでdockerコンテナを立ち上げます。

docker-compose up -d

以下のような出力がされたら成功です。

laravel-docker-compose-example_mysql_1 is up-to-date
laravel-docker-compose-example_app_1 is up-to-date
laravel-docker-compose-example_web_1 is up-to-date
Creating laravel-docker-compose-example_redis_1 ... done

次にQueueをRedisに設定します。

laravelの.env ファイルを開いてQueueをRedisに設定します。

以下のように設定しましょう。

# QUEUE_CONNECTION=sync

QUEUE_CONNECTION=redis

...


REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379

dockerの場合hostの値はサービス名(この場合はredis)を指定すると名前解決してくれます。

dockerを再起動します。

docker-compose restart

dockerコンテナに入ってキューに投入された新しいジョブを処理する、キューワーカを起動します。


docker-comopse exec app bash cd my-laravel-app php artisan queue:work

この状態でhttp://localhost:8000 にアクセスしてみましょう。

テストJobをQueueに追加しました! が画面に表示され10秒後にJobが実行されログファイルに書き込まれます。

これでRedisの設定は完了です!

Supervisorを設定する

SupervisorとはLinuxオペレーティングシステムのプロセスモニタで、もしqueue:work プロセスが落ちても自動的に起動してくれます。

それでは早速Supervisorの設定をしていきましょう。

まずはappにSupervisorをインストールする記述をします。

docker/php/Dockerfile を開いて以下を追加します。

RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql \
    && apt-get install -y supervisor # 追加

次にSupervisorの設定をします。

docker-compose.yml に以下の記述を追加します。(最後の一行)

app:
    build: ./docker/php
    depends_on:
    - mysql
    volumes:
      - .:/var/www/html
      - ./docker/supervisor/laravel-worker.conf:/etc/supervisor/conf.d/laravel-worker.conf

次にdocker/supervisor/laravel-worker.conf ファイルを作成し、以下のように記述しましょう。

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/html/my-laravel-app/artisan queue:work redis --sleep=3 --tries=3
autostart=true
autorestart=true
user=root
numprocs=8
redirect_stderr=true
stdout_logfile=/var/www/html/my-laravel-app/storage/logs/worker.log

この設定ファイルを修正するとSupervisorの設定を変えることができます。

docker-compose up -d --build

Supervisorを起動します。

docker-compose exec app service supervisor start

以下の出力とともにSupervisorが立ち上がります。

Starting supervisor: supervisord.

再びhttp://localhost:8000 にアクセスしてみましょう。

ログがファイルに書き込まれます。

先ほどとの違いはSupervisorの処理がstorage/logs/worker.log に書き込まれます。

[2018-12-06 14:35:36][ZJoKgcfL0i6Tu5rYo3jB928tTu30LEKD] Processing: App\Jobs\TestJob
[2018-12-06 14:35:37][e6URlogoFZ6muQbxJ1pYu4Ip8ONhAEs0] Processing: App\Jobs\TestJob
[2018-12-06 14:35:37][ZJoKgcfL0i6Tu5rYo3jB928tTu30LEKD] Processed:  App\Jobs\TestJob
[2018-12-06 14:35:37][e6URlogoFZ6muQbxJ1pYu4Ip8ONhAEs0] Processed:  App\Jobs\TestJob

これにてSupersiorの設定は完了です!

以上でLaravelでRedisとSupervisorを導入してQueue/Jobを扱えるようになりました!

本格的なLaravelアプリ開発ではJobが欠かせないのでぜひマスターしてください。それでは〜

**追記:続編書きました!ぜひご覧ください!! **

The following two tabs change content below.

riri

半年おきくらいにバックエンドとフロントエンドを行ったり来たり。 25歳。 将棋好き。

Dockerの最近記事

  1. Laravel HorizonでQueue/Jobを眺める

  2. LaravelでRedisとSupervisorを導入してQueue/Jobを扱う【doc…

  3. Laravelの環境(Nginx+MySQL+PHP)をdocker-composeでイチ…

関連記事

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。