Archive for the ‘supervisor’ Category

SuperVisorでイベント監視(crashmail編)

水曜日, 11月 30th, 2011

SuperVisorの基本は前回の記事を参照してください。

SuperVisorにおけるイベント監視のメカニズム

supervisordが検知したサブプロセスのイベントを、
事前に定義しておいたeventlistenerが処理する。
eventlistenerは自作する事ができるし、
よくありがちな処理をするeventlistenerはsuperlanceというpythonパッケージで提供されている。

公式のEventsドキュメントを読む限りでは様々なイベントの補足ができるようだ。
イベントの種類

– PROCESS_STATE_STARTING | プロセスが起動準備状態になった
– PROCESS_STATE_RUNNGING | プロセスが起動した
– PROCESS_STATE_BACKOFF | プロセスの起動に失敗した
– PROCESS_STATE_STOPPING | プロセスが停止準備状態になった
– PROCESS_STATE_STOPPED | プロセスが正常に停止した
– PROCESS_STATE_EXITED | プロセスがcrashした
– PROCESS_STATE_FATAL | プロセスの起動を指定されたretry回数分試みたが失敗した
– PROCESS_STATE_UNKNOWN | supervisordにエラーが発生した
– PROCESS_LOG | プロセスがログファイルを吐いた
– PROCESS_COMMUNICATION_STDOUT | プロセスが標準出力の支持を出した
– PROCESS_COMMUNICATION_STDERR | プロセスが標準エラー出力の支持を出した
– SUPERVISOR_STATE_CHANGE_STARTING | supervisordが起動準備状態になった
– SUPERVISOR_STATE_CHANGE_STOPPING | supervisordが停止準備状態になった
– TICK_5 | 毎5秒ごとに発生するイベント
– TICK_60 | 毎分ごとに発生するイベント
– TICK_3600 | 毎時ごとに発生するイベント

今回はapacheがcrashした時にメールで通知したかったため、
eventlistenerを自作しようと思っていたがEventsのドキュメントを見ていて
superlanceというpluginパッケージがあることを発見。
ドキュメントを読むとsuperlanceには下記のeventlistenerをパッケージングしているとのこと。
httpok
TICK_系のイベントを監視し定期的にhttpサーバの死活チェックを行い、request失敗やtimeoutの場合再起動してメールするplugin
crashmail
プロセスが死んだらメールするplugin
memmon
プロセスが閾値以上のメモリを使っていたらrestartしてメールするplugin

crashmailが今回の要件にマッチしてそうなのでこれを使うことにした。

superlanceのインストール

supervisor同様にeasy_installでインストールできる。

$ sudo easy_install superlance

crashmailの設定

eventlistenerは通常のデーモンと同じように定義します、つまりeventlistnerもデーモン化されるということです。
詳しくは設定ファイルのリファレンスを参照。

通常のデーモンはprogramと記述するところをeventlistenerに変更する。
eventsという設定が必要で、監視するイベントを定義する。(コンマ区切りで複数指定可)

$ sudo vi /etc/supervisord.conf
[eventlistener:crashmail]
command=/usr/local/bin/crashmail -p apache2 -m dev@example.com
events=PROCESS_STATE_EXITED

今回の設定ではapacheがcrashした時にdev@example.comにアラートメールを送信する事ができる。

crashmailをsupervisordの監視下に追加する

supervisorctlコマンドでeventlistenerを追加してみましょう。

$ sudo /usr/local/bin/supervisorctl update
$ sudo /usr/local/bin/supervisorctl status
apache2 RUNNING pid 50197, uptime 2:00:06
crashmail RUNNING pid 48783, uptime 0:00:01

statusコマンドの実行結果でcrashmailがRUNNINGになっていれば成功です。

crashmailの動作テスト

今回はapache2がcrashした場合のテストをしたいため、httpdをkillallしてみる。

$ sudo killall -9 httpd

killallするとhttpdが一度死んでsupervisorによって蘇ります。
さらにcrashmailがhttpd死亡イベントを検知して以下のようなメールをdev@example.comに
送っていれば正常に動作したことになります。

subject: apache2 crashed at 2011-11-30 11:58:23,804
to: dev@example.com
body:
Process apache2 in group apache2 exited unexpectedly (pid 12536) from state RUNNING

※PROCESS_STATE_FATALやPROCESS_STATE_BACKOFFも補足してくれるのかソースを読んでみたが、どうやらPROCESS_STATE_EXITEDをハードコードしているので補足したい場合は自前でeventlistenerを作成する必要がある。
crashmail.py

    def runforever(self, test=False):
        while 1:
            # we explicitly use self.stdin, self.stdout, and self.stderr
            # instead of sys.* so we can unit test this code
            headers, payload = childutils.listener.wait(self.stdin, self.stdout)

            if not headers['eventname'] == 'PROCESS_STATE_EXITED':
                # do nothing with non-TICK events
                childutils.listener.ok(self.stdout)
                if test:
                    self.stderr.write('non-exited event\n')
                    self.stderr.flush()
                    break
                continue

SuperVisor導入(基本編)

火曜日, 11月 29th, 2011

SuperVisorとは

SuperVisorはデーモンプロセスの管理をしてくれるデーモンです。
僕が知っている似たようなデーモンとしてdaemontoolsがあります。
SuperVisorはlinuxやmacで動作します。

便利な機能
– プロセスクラッシュ時に自動で再起動
– ログの管理
– イベントの監視ができる (デーモンがcrashした時にメール通知などが簡単にできる)
– 設定ファイルがシンプル(1ファイルでok)
– 標準でwebI/Fが付属されている

インストール

SuperVisorはpythonで書かれているのでpythonが必要です。
※pythonのインストール方法は割愛します。

pythonにはeasy_installというお手軽インストーラパッケージがあり、このコマンドを使って
SuperVisorをインストールすることができます。

# easy_installをインストール
$ wget http://peak.telecommunity.com/dist/ez_setup.py
$ chmod 755 ./ez_setup.py
$ sudo python ./ez_setup.py

# supervisorをインストール
$ sudo easy_install supervisor

成功すると下記コマンドがシステムにインストールされるはずです。

supervisord // supervisor本体
supervisorctl // supervisor管理コマンド
echo_supervisor_conf // 設定ファイル生成script

設定

シンプルに設定ファイル1つで行えます。
※apacheのようにincludeコマンドを使って複数の設定ファイルに分けることも可能です。
詳しくは設定ファイルのリファレンスを参照。

echo_supervisor_confは設定例を標準出力してくれるコマンドなので利用して生成します。

$ sudo sh -c “echo_supervisor_conf > /etc/supervisord.conf”

必要最低限の設定を記述します。

$ sudo vi /etc/supervisord.conf
[unix_http_server]
file=/tmp/supervisor.sock ; (the path to the socket file)

[supervisord]
logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[program:apache2]
command=/usr/sbin/httpd -c “ErrorLog /dev/stdout” -DFOREGROUND
redirect_stderr=true
stdout_logfile=/var/log/apache2/log.out
stderr_logfile=/var/log/apache2/log.err

これはapacheをデーモン化する例です。
[progoram:YYY]のようにprogramブロックを追加していけばどんどん管理するデーモンを増やせます。

supervisord起動

それでは設定も終わったことですしsupervisordを起動してみましょう。

$ sudo /usr/local/bin/supervisord
$ sudo /usr/local/bin/supervisorctl status
apache2 RUNNING pid 12104, uptime 0:00:02

statusコマンドの実行結果でapache2がRUNNINGになっていれば成功です。

運用

SuperVisor管理下のプロセスの制御は全てsupervisorctlコマンドで行う事になります。

起動

$ sudo supervisorctl start apache2

再起動

$ sudo supervisorctl restart apache2

停止

$ sudo supervisorctl stop apache2

サブプロセスの設定変更を反映
下記コマンドを実行すれば反映可能。
ただし、全てのサブプロセスが再起動してしまう。

$ sudo kill -HUP `cat /tmp/supervisord.pid`

ちょっと面倒くさいが下記コマンドを実行すれば指定のプロセスのみ
設定を反映して再起動できる。

$ sudo supervisorctl update apache2
$ sudo supervisorctl stop apache2
$ sudo supervisorctl remove apache2
$ sudo supervisorctl add apache2

コマンドヘルプ
コマンドの詳細が知りたければhelpを実行する。
公式サイトにもコマンドの詳細は載ってなかった。

$ sudo supervisorctl help start