Laravelのキュープロセスをsupervisorで管理

キューを実行するプロセスをsupervisorを使って管理するまでのまとめ。
ほぼsupervisorの記事な気もする。

参考記事

* Production-Ready Beanstalkd with Laravel 4 Queues
http://fideloper.com/ubuntu-beanstalkd-and-laravel4
* PHP+Kestrel+Supervisorでお手軽タスクキューイング
http://blog.asial.co.jp/875
* python:supervisor
http://www.tomoyan.net/dokuwiki/python/supervisor

・supervisorのinstall

```
easy_install supervisor
```

上記コマンドでsupervisorがinstallされる。
設定ファイルを作る

```
echo_supervisord_conf > /etc/supervisord.conf
```

/etc/supervisord.confにsupervisorの設定が書き出される

設定をちょいちょい必要に合わせて変更する。自分の設定をデフォルトと比べるとこんな感じ

```
echo_supervisord_conf | diff - /etc/supervisord.conf
```

```
< ;[inet_http_server]         ; inet (TCP) server disabled by default
< ;port=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)
---
> [inet_http_server]         ; inet (TCP) server disabled by default
> port=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)
22c22,23
< logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
---
> ;logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
> logfile=/var/log/supervisord/supervisor.log ; ログディレクトリを/var/log/以下に
26c27,28
< pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
---
> ;pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
> pidfile=/var/run/supervisord/supervisor.pid ; pidディレクトリを/var/run/以下に
47c49
< ;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
---
> serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
138,139c140,141
< ;[include]
< ;files = relative/directory/*.ini
---
> [include]
> files = /etc/supervisord.d/*.ini ; supervisord.d以下の設定を読み込む
```

設定に合わせてディレクトリを作成

* supervisorで管理するプロセス設定ファイルのディレクトリ

```
mkdir /etc/supervisord.d
```

* pidファイル生成ディレクトリ

```
mkdir /var/run/supervisord
```

* ログディレクトリ

```
mkdir /var/log/supervisord
```

supervisorは

```
supervisord
```

ってコマンド打てば起動するけどsupervisor知らない人も使う場合そんなん知りませんやんって話になりかねんのでinit.d以下に実行ファイルを作成

```
vi /etc/init.d/supervisord
```

こんな感じ

```
#!/bin/bash
#
# supervisord  Startup script for the Supervisor
#
# chkconfig: - 70 60
# description: Supervisor is a client/server system that allows its users to \
#              monitor and control a number of processes on UNIX-like operating systems.
# processname: supervisord
# config:  /etc/sysconfig/supervisord
# pidfile: /var/run/supervisor/supervisor.pid
#
### BEGIN INIT INFO
# Provides: supervisord
# Short-Description: start and stop Supervisor
# Description: Supervisor is a client/server system that allows its users to
#  monitor and control a number of processes on UNIX-like operating systems.
### END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

if [ -f /etc/sysconfig/supervisord ]; then
    . /etc/sysconfig/supervisord
fi

supervisord=${SUPERVISORD-/usr/bin/supervisord}
prog=supervisord
pidfile=${PIDFILE-/var/run/supervisord/supervisor.pid}
lockfile=${LOCKFILE-/var/lock/subsys/supervisord}
RETVAL=0
STOP_TIMEOUT=${STOP_TIMEOUT-3}

start() {
    echo -n $"Starting $prog: "
    daemon $supervisord --pidfile=${pidfile}
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && touch ${lockfile}
    return $RETVAL
}

stop() {
    echo -n $"Stopping $prog: "
    killproc -p ${pidfile} -d ${STOP_TIMEOUT} $supervisord -QUIT
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}

restart() {
    echo -n $"Reloading $prog: "
    killproc -p $pidfile $supervisord -HUP
    RETVAL=$?
    echo

#!/bin/bash
#
# supervisord  Startup script for the Supervisor
#
# chkconfig: - 70 60
# description: Supervisor is a client/server system that allows its users to \
#              monitor and control a number of processes on UNIX-like operating systems.
# processname: supervisord
# config:  /etc/sysconfig/supervisord
# pidfile: /var/run/supervisor/supervisor.pid
#
### BEGIN INIT INFO
# Provides: supervisord
# Short-Description: start and stop Supervisor
# Description: Supervisor is a client/server system that allows its users to
#  monitor and control a number of processes on UNIX-like operating systems.
### END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

if [ -f /etc/sysconfig/supervisord ]; then
    . /etc/sysconfig/supervisord

    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status -p ${pidfile} $supervisord
        RETVAL=$?
        ;;
    restart)
        stop
        start
        ;;
    reload)
        reload
        ;;
    *)
        echo $"Usage: $prog {start|stop|restart|reload|status}"
        RETVAL=2
esac

exit $RETVAL
```

さっき作ったディレクトリとかの設定がここに書いてあるものと違うと怒られるので注意。

これで

起動

```
/etc/init.d/supervisord start
```

停止

```
/etc/init.d/supervisord stop
```

リスタート

```
/etc/init.d/supervisord restart
```

ができるようになった。どのタイミングで起動させるかはインフラチームと要相談で。

ここまで終わったところでLaravelのartisanコマンドをsupervisorで管理する設定ファイルを作る

```
vi /etc/supervisord.d/laravelqueue.ini
```

さっき作った/etc/supervisord.d/ディレクトリ以下にsupervisorに管理してほしいプロセスの設定ファイルをつくる。

中身はこんな感じ

```
[program:laravelqueue]
command=php artisan queue:listen ; 管理するコマンド。今回はキューなのでこんな感じ
directory=Laravelプロジェクト ;上記コマンドを実行するディレクトリ。上記commandのartisanの場所を指定しても可
stdout_logfile=Laravelプロジェクト/app/storage/logs/laravelqueue_supervisord.log ; supervisorのログを管理するファイル。
redirect_stderr=true
process_name=%(program_name)s_%(process_num)02d
numprocs=5 ; ワーカーを**プロセス起動する。今回は5
autostart=true ; supervisord起動時に自動的に起動する
autorestart=true ; プロセスが死んでも自動的に起動する
user=root ; コマンドを実行するユーザー。お好みで変更してちょ
```

stdout_logfileはsupervisorがこのプロセスを実行した際にログをはくファイルを指定。

```
vi Laravelプロジェクト/app/storage/logs/laravelqueue_supervisord.log
```

という感じで作っておく。

これで準備完了。

supervisorを起動してみる

```
/etc/init.d/supervisord start
```

問題なければこんな感じの表示が


```
Starting supervisord: /usr/lib/python2.6/site-packages/supervisor-3.0-py2.6.egg/supervisor/options.py:295: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
  'Supervisord is running as root and it is searching '
                                                           [  OK  ]
```

プロセスが実行されているか確認してみる

```
supervisorctl status
```

こんな感じに

```
laravelqueue:pointqueue_00         RUNNING    pid 25309, uptime 0:01:12
laravelqueue:pointqueue_01         RUNNING    pid 25308, uptime 0:01:12
laravelqueue:pointqueue_02         RUNNING    pid 25307, uptime 0:01:12
laravelqueue:pointqueue_03         RUNNING    pid 25306, uptime 0:01:12
laravelqueue:pointqueue_04         RUNNING    pid 25310, uptime 0:01:12
```

ためしに1プロセスkillしてみる

```
kill 25310
```

確認すると

```
supervisorctl status
```

```
laravelqueue:pointqueue_00         RUNNING    pid 25309, uptime 0:02:16
laravelqueue:pointqueue_01         RUNNING    pid 25308, uptime 0:02:16
laravelqueue:pointqueue_02         RUNNING    pid 25307, uptime 0:02:16
laravelqueue:pointqueue_03         RUNNING    pid 25306, uptime 0:02:16
laravelqueue:pointqueue_04         RUNNING    pid 25911, uptime 0:00:02
```

pid 25911として復活してる。やっほい。

これでキューが登録され次第実行されていくための設定終わり。
キューを使う設定が整ったぞー。多分。