本文書ではLaravelのキューにたまったジョブを処理するワーカープロセスの監視を行うために利用できるSupervisorのインストールと使用方法について説明を行っています。

キューやジョブ、ワーカーについては以下の文書が参考になります。

Supervisorを利用するバックグラウンドでワーカープロセスを監視し、プロセスが停止した場合は自動で起動を行ってくれます。

SupervisorはLinuxのOS上のプロセスを監視や管理に利用することができます。Laravel専用ではありません。

Laravel6.3のUbuntu18.04.3上で動作確認を行っています。

インストールなどの手順についてはLaravelの公式マニュアルを参考に行っています。

Supervisorの設定

Supervisorのインストール

apt-getコマンドでsupervisorのインストールを行います。


$ sudo apt-get install supervisor

インストールしたsupervisorのバージョンの確認を行います。apt-getでは3.3.1のバージョンがインストールされています。


$ supervisord -v
3.3.1

Laravel worker用ファイルの作成

supervisorの設定ファイルは/etc/supervisorディレクトリの下に保存されています。プロセス毎に設定ファイルを作成することができ、設定ファイルは/etc/supervisor/conf.dのなかに作成します。

conf.dディレクトリに作成するファイル名は、laravel-worker.confファイルとします。設定ファイルの内容は下記のように記述します。


[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /home/reffect/laravel6/artisan queue:work --sleep=3 --tries=3
autostart=true
autorestart=true
user=root
numprocs=2
redirect_stderr=true
stdout_logfile=/home/reffect/laravel6/storage/logs/worker.log

主な設定値は下記の通りです。

  • process_nameは上記の設定では、laravel-worker_00といった名前になり、プロセスの数をnumprocsを増やすと最後の2桁の数字が01, 02…という名前になります 。
  • commandはワーカープロセスを起動するコマンドを記述します。パスは各環境に合わせて設定を行ってください。
  • autostartはsupervisorデーモンを起動した時に一緒に起動するかを設定します。
  • autorestartはプロセスが停止した場合に自動で再起動するか設定します。
  • numprocsは起動するワーカープロセスの数で2に設定すると2つのワーカープロセスが起動します。
  • stdout_logfileはワーカープロセスのログファイルのパスです。各環境に合わせて設定を行ってください。

Supervisordデーモンの起動

supervisorではsupervisorctlコマンドを利用してプロセスの管理を行いますが、 supervisorctl コマンドを利用するためにはsupervisorデーモンを起動しておく必要があります。以下のserviceコマンドでsupervisordデーモンのステータス確認/起動/停止を行うことができます。

インストール直後でステータスを確認するとステータスはis not runningと表示されます。


$ sudo service supervisor status
supervisord is  not running.

supervisordデーモンの起動は下記のように行います。


$ sudo service supervisor start
Starting supervisor: supervisord.
$ sudo service supervisor status
supervisord is running

supervisordデーモンを停止したい場合は下記のように行います。


$ sudo service supervisor stop
Stopping supervisor: supervisord.

もし起動していない状態でsupervisorctlコマンドを実行すると下記のようなエラーが表示されます。


$ sudo supervisorctl status
unix:///var/run/supervisor.sock no such file
$ sudo supervisorctl reread
error: <class 'socket.error'>, [Errno 2] No such file or directory: file: /usr/lib/python2.7/socket.py line: 228
supervisorctlを使用する前にservice supervisor statusコマンドでデーモンが起動しているか確認を行い、起動していない場合はservice supervisor startコマンドで起動を行ってください。

supervisorctlコマンドの使用方法

supervisorctlコマンドでプロセスの管理を行います。どのようなオプションをとるかはhelpオプションをつけて実行すると確認することができます。


$ sudo supervisorctl help

default commands (type help <topic>):
=====================================
add    exit      open  reload  restart   start   tail
avail  fg        pid   remove  shutdown  status  update
clear  maintail  quit  reread  signal    stop    version
supervisorctlのバージョンによってhelpで表示されるオプションの数は異なります。

現在のプロセスの状態はstatusで確認することができます。RUNNIGとなっていれば現在起動しています。


$ sudo supervisorctl status
laravel-worker:laravel-worker_00   RUNNING   pid 1810, uptime 0:02:41
laravel-worker:laravel-worker_01   RUNNING   pid 1812, uptime 0:02:41

プロセスを停止したい場合はstopコマンドで行うことができます。


$ sudo supervisorctl stop laravel-worker:*
laravel-worker:laravel-worker_00: stopped
laravel-worker:laravel-worker_01: stopped
$ sudo supervisorctl status
laravel-worker:laravel-worker_00   STOPPED   Oct 16 01:30 PM
laravel-worker:laravel-worker_01   STOPPED   Oct 16 01:30 PM

停止したプロセスはstartコマンドで起動することができます。


$ sudo supervisorctl start laravel-worker:*
laravel-worker:laravel-worker_00: started
laravel-worker:laravel-worker_01: started

startの後ろのプロセス名は下記のように記述する必要があります。stopの場合はstartをstopに変更したら同じです。


$ sudo supervisorctl start
Error: start requires a process name
start             Start a process
start :*         Start all processes in a group
start       Start multiple processes or groups
start all               Start all processes

設定ファイルの更新

laravel-worker.confファイルの書き換えを行うと動的には変更が行われないため、 supervisorctlコマンドにrereadオプション、reloadオプションをつけて実行する必要があります。reloadではなくupdateでも可能です。

設定ファイルの反映を確認するためにnumprocsを2から3に設定してみましょう。変更後、rereadコマンドを実行するとファイルに変更があったことを示すメッセージchangedが表示されます。


$ sudo supervisorctl reread
laravel-worker: changed

もし設定ファイルに変更がない場合は下記のメッセージが表示されます。


$ sudo supervisorctl reread
No config updates to processes

rereadでは設定ファイルの再読み込みを行っただけなので、statusを確認してもプロセスが2つから変化はありません。


$ sudo supervisorctl status
laravel-worker:laravel-worker_00   RUNNING   pid 1838, uptime 0:02:29
laravel-worker:laravel-worker_01   RUNNING   pid 1839, uptime 0:02:29

reloadを実行しましょう。実行するとプロセスが3つなっていることを確認することができます。設定内容を反映させるためには、rereadだけではなくreloadも必要であることがわかります。


$ sudo supervisorctl reload
Restarted supervisord
$ sudo supervisorctl status
laravel-worker:laravel-worker_00   RUNNING   pid 1887, uptime 0:00:02
laravel-worker:laravel-worker_01   RUNNING   pid 1888, uptime 0:00:02
laravel-worker:laravel-worker_02   RUNNING   pid 1889, uptime 0:00:02
reloadだけではなくupdateでも反映させることができます。

プロセス再起動の動作確認

プロセスのプロセスIDを確認します。


$ sudo supervisorctl status
laravel-worker:laravel-worker_00   RUNNING   pid 1887, uptime 0:00:02
laravel-worker:laravel-worker_01   RUNNING   pid 1888, uptime 0:00:02
laravel-worker:laravel-worker_02   RUNNING   pid 1889, uptime 0:00:02

killコマンドを利用してpid 1887のプロセスを強制的に停止します。強制停止直後にプロセスを確認すると新たに1923としてプロセスが起動していることがわかります。


$ sudo kill -9 1887
$ sudo supervisorctl status
laravel-worker:laravel-worker_00   RUNNING   pid 1923, uptime 0:00:02
laravel-worker:laravel-worker_01   RUNNING   pid 1888, uptime 0:05:34
laravel-worker:laravel-worker_02   RUNNING   pid 1889, uptime 0:05:34

laravel-worker.conf作成時にはautorestartをtrueに設定していました。これをfalseに変更して動作確認を行います。

変更を行ったら、rereadとreload/updateを行ってください。

statusを確認すると3つのプロセスが確認できます。pid 1947のプロセスを強制亭します。


$ sudo supervisorctl status
laravel-worker:laravel-worker_00   RUNNING   pid 1947, uptime 0:00:03
laravel-worker:laravel-worker_01   RUNNING   pid 1948, uptime 0:00:03
laravel-worker:laravel-worker_02   RUNNING   pid 1949, uptime 0:00:03

ステータスを確認するとRUNNINGではなくEXITEDになっていることがわかります。autorestartをfalseに設定すると自動で起動が行われないことがわかります。


$ sudo kill -9 1947
$ sudo supervisorctl status
laravel-worker:laravel-worker_00   EXITED    Oct 16 01:06 PM
laravel-worker:laravel-worker_01   RUNNING   pid 1948, uptime 0:01:37
laravel-worker:laravel-worker_02   RUNNING   pid 1949, uptime 0:01:37

停止したプロセスは下記のコマンドを実行すると起動することができます。


$ sudo supervisorctl start laravel-worker:*
laravel-worker:laravel-worker_00: started

ジョブを実行しログの中身の確認

Laravelを利用してキューを使ってSendWelcomeMailというジョブを実行します。

storage/logs/worker.logの中身を確認するとsupervisorで起動したワーカーがキューにたまったジョブを処理していることを確認することができます。


[2019-10-16 04:11:03][2] Processing: App\Jobs\SendWelcomeMail
[2019-10-16 04:11:06][2] Processed:  App\Jobs\SendWelcomeMail