gunicorn を daemontools で監視する手順

gunicornをdaemontoolsで死活監視したことあるか的な質問がどこかに流れていたので、手順を簡単にメモっておく。OSの環境は debian(leny)を例にとります。 gunicorn て何よ?、daemontoolsて何よ?って人はこちからどうぞ。

1. daemontoolsのインストール

よくネットで調べると「daemontools-installer」が出てくるけど、もう最近のでは無いというか普通にdaemontoolsだけでインストールできるようになってる。

sudo apt-get install daemontools daemontools-run

2. gunicorn のインストール

お使いのPython環境にインスコ

pip install gunicorn

3. 簡単なWSGIアプリ用意

実際に動くアプリを用意しなければしょうがないので、gunicorn本家からコピペ。

http://gunicorn.org/run.html

# -*- coding: utf-8 -
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

def app(environ, start_response):
    """Simplest possible application object"""
    data = 'Hello, World!\n'
    status = '200 OK'
    response_headers = [
        ('Content-type','text/plain'),
        ('Content-Length', str(len(data)))
    ]
    start_response(status, response_headers)
    return iter([data])

こいつを test.pyという名前で用意。試しに何もかんがえずに、下記のようにコマンドをうってみて、gunicornが起動する事を確認しませう。

gunicorn --wokers=2 test:app

これで多分起動するはず。確認できたら一旦killしておいてgunicornが立ち上がってない事を確認してください。

4. gunicorn 設定ファイル

上の例のように毎回 --workers とかパラメータを渡してもいいけど、それはメンドクサイので、gunicornの設定はファイル化しておいた方が吉。ここではgunicorn_conf.pyとする。

bind = "127.0.0.1:8000"
logfile ="/var/log/gunicorn/gunicorn.log"
workers = 1

4. runスクリプトの用意

deamontoolsで監視するとき、そのサービスの起動スクリプト(runファイル)が必要となる。とりあえず、これも公式のをコピ。。。拝借して試してみる。

gunicorn/gunicorn_rc at master · benoitc/gunicorn · GitHub

こいつを、run.shとかいう名前で保存してみる。

#!/bin/sh

GUNICORN=/usr/local/bin/gunicorn  #/usr/local/binにインストールされてるかどうかは確実ではない。お使いの環境によるのでしらべてくだしあ。
ROOT=/home/bucho
PID=/var/run/gunicorn.pid

APPt=test:app

if [ -f $PID ]; then rm $PID fi

cd $ROOT
exec setuidgid www $GUNICORN -c $ROOT/gunicorn.conf.py --pidfile=$PID $APP
  • wwwグループのwwwユーザーで実行させると仮定する。

と。ここまで早足で来たが、いまの構造を一旦整理、今回のディレクトリ構成はこんな感じ

■ 実作業場所
/home/bucho/
            ├── run.sh                   #=> gunicornのrunファイル
            ├── test.py                   #=> WSGIアプリ
            └── gunicorn.conf.py    #=> Gunicornの設定ファイル

■ deamontools用サービスディレクトリ
/var/bucho
           ├── run                         #=> /home/bucho/run.sh の シンボリックリンク 
           └── log                          #=> daemontools用ログディレクトリ 
                      ├── run      #=> ログ用のrunスクリプト
                      └── main 
 
■ deamontoolsの実サービスディレクトリ 
/etc/services/bucho/                   #=> /var/bucho以下の構成が最終的にここにできると監視開始
                                                    #=> 後述する作業で、buchoディレクトリも含めて一気作成登録するので
                                                    #=> 今はbuchoディレクトリ作らないでよい。
          
■ gunicorn のPIDファイル
/var/run/gunicorn.pid                  #=> gunicornのプロセスIDが記載されるファイル

■ gunicornのログファイル
/var/log/gunicorn/gunicorn.log   #=> gunicornのログファイル

  • runファイルは実行権限が必要
  • /var/log/gunicornとか書き込む場所にはwwwグループに書き込み権限必要

/var/bucho/log/runファイル は そのサービスのログを取るためのスクリプトを設置する。ぶっちゃけどういう内容を書いたらいいのかよくわかってなす。
今のところは、こんな内容を書いて、mainディレクトリ以下にmultilogの結果が出るようにしておく。

#!/bin/sh

exec 2>&1
exec setuidgid www multilog t ./main

5. サービスの登録

ここまでの作業で、上のディレクトリ構成の/var/buchoと/home/bucho以下のファイル群を用意したとする。こんどは実際に、サービスを、daemontoolsの監視下におくために登録する作業が必要となる。

sudo update-service --add /var/bucho

というコマンドを打つと登録完了、これは。/var/bucho以下の内容をdaemontools(/etc/service以下)に登録するよという意味。実際にサービス登録されたかどうかは、下記のようになコマンドを打てばよい。

sudo svstat /etc/service/bucho

起動からの経過時間とかでるので、それで確認できるかと。

実は、他のブログとかを参考にしていると、「update-service」を使わずに、/etc/service以下にbuchoディレクトリを作って、次にrunファイルを作ってという、やり方が紹介されているがあれは簡便化して紹介しているだけだと思う。実務的な作業の場合にはupdate-serviceを使った方が良いとのこと。

理由としては、daemontoolsは起動していると、常にsvscanという監視サービスが/etc/service以下をチェックしているので、そこで、いろいろ作業していると何か不具合が起きる可能性もあるから。 なので、/var/buchoという登録サービス用の一式をそろえた上で、update-serviceで一気に登録した方がよい。

という感じで、作業完了。本当にgunicronのプロセスがあがってるかどうかは、「ps aux | grep gunicorn」でも確認できるはず。試しにgunicornのプロセスをkill -9してみて、別のプロセスIDで再起動される事を確認すれば良い。

以下は daemontoolsと仲良くなって幸せに至るためのコマンド類

幸せにいたるコマンド類

起動:            sudo svc -u /etc/service/bucho
停止:             sudo svc -d /etc/service/bucho
再起動:          sudo svc -t /etc/service/bucho
稼働状況確認: sudo svstat /etc/service/bucho

参考

この辺も参考にさせていただきました。ありがとうございます。

@aodag にーやん thx!

余談

同じような監視系のツールで python製のsupervisorというのも良いらしいのでそっちも試そうかと。