« パソナテック10周年記念 シリコンバレーツアー(後編) | メイン | PHPで携帯位置情報を扱うライブラリ「Geomobilejp_Converter」を作りました »

daemontoolsでデーモン管理
このエントリーをはてなブックマークに追加 このエントリーをlivedoorクリップに追加

Emacsでbackward-charをC-lに割り当てているbokkoです。「指相撲で相手の指に届かないくらい指が短いので一回も勝ったことがないんです。だからそんな短い指でC-bなんて押してたら指が痛いんです」と言ってもなかなか信じてもらえないのですが、そんな私でも(global-set-key "\C-l" 'backward-char)というelispを評価するだけで快適にプログラミングさせてくれるEmacsが大好きです。


と、タイトルと関係ない話はこれくいらいにしておいて、今日はdaemontoolsのお話です。


daemontools

daemontoolsは異常終了してしまったデーモンプロセスを再起動してくれたり、ログローテートを肩代わりしてくれたりするなど、デーモンの制御や管理、監視を行うプログラムの集まりです。例えば、以下のようなプログラムが含まれています。

  • supervise
    • デーモンの起動、監視
  • svc
    • superviseによって監視されているデーモンの制御
  • svstat
    • 指定したデーモンの状態を出力
  • setuidgid
    • ユーザIDとグループIDを変更
  • multilog
    • デーモンプログラムの出力をロギング

ほかにもいろいろありますが、詳しくは本家のマニュアル(日本語版)を見るとよいでしょう。

インストール

ソースコードがこちらで、SRPMがこちらで配布されています。Linuxディストリビューションによってはapt-getでインストールすることもできますが、その場合は名前がdaemontoolsではなく、svtoolsになっているものがあります(Ubuntuは後者でした)。インストールすると、/commandに各プログラムが配置され、/にserviceというディレクトリが作成されます。daemontoolsでデーモンを管理する場合、この/serviceディレクトリにデーモンの起動スクリプトやログ収集のためのスクリプトを配置します。

デーモンの登録

デーモンを登録するには/service以下に登録したいデーモンの起動スクリプトとログ収集のためのスクリプトを配置します。

$ mkdir /var/daemon
$ mkdir /var/daemon/log
$ mkdir /var/daemon/log/main
$ chmod 1755 /var/daemon
$ chmod +x /var/daemon/run
$ chmod +x /var/daemon/log/run
$ chown hoge:fuga /var/daemon/log/main
$ ln -s /var/daemon /service

/var/daemon/run

#!/bin/sh
exec 2>&1 # エラー出力を標準出力へ
exec setuidgid hoge /usr/bin/daemon

/var/daemon/log/run

#!/bin/sh
exec 2>&1 # エラー出力を標準出力へ
exec setuidgid hoge multilog t ./main

runを実行したプロセス自身をデーモン化しなければいかないので、必ずexecを付けます。また、runで実行するプロセスはフォアグラウンドで起動させなければいけません。

追記:(2008/07/24)

/var/daemon/runの内容が/var/daemon/log/runのものになっており、/var/daemon/runの内容が抜けていたのを修正しました。また、現行のdaemontools-0.76ではstickyビットを立てる必要はありません。ご指摘ありがとうございます。>fumiyasさん

デーモンの起動制御

/service以下のデーモンを起動するにはsvscanを使うとよいでしょう。

$ sh -c 'svscan /service &'

↑を実行すると/serviceディレクトリ以下にあるすべてのデーモンに対してsuperviseによるデーモンの監視が行えます。なんらかの原因でデーモンが終了してしまってもsuperviseが自動的にデーモンを再起動してくれます。ただ、デーモンプログラム自体に問題があって起動できない場合、何度も再起動を試み、ずっとログに起動失敗のメッセージを書き込み続けてしまうので注意しましょう。

OS起動時からdaemontoolsに関連するプログラムを起動しておく場合は、/etc/inittabに以下の記述をしておくとよいでしょう。

SV:123456:respawn:/command/svscanboot      

svcでデーモンに命令を発行する

svcコマンドを使うと指定したデーモンに対して以下のような命令を発行することができます。

$ svc -u /service/daemon # 起動
$ svc -d /service/daemon # 一時停止
$ svc -t /service/daemon # 再起動
               ・
               ・
               ・

svstatで状態確認

svstatを使うと指定したデーモンの状態を確認することができます。

$ svstat /service/daemon # 起動中
/service/daemon: up (pid 8131) 3 seconds
$ svstat /service/daemon # 停止中
/service/daemon: down (pid 8131) 57 seconds, normally up

ただ、たまにdaemontools側から起動しているように見えているだけの時があるので注意しましょう。詳しくは後述します。

ロギング

デーモンプログラムの出力は/var/daemon/log/runで実行しているmultilogによって/var/daemon/log/main以下に保存されます。multilogもdaemontoolsに含まれるツールの一つです。保存されるログはそのままでは見づらいので、同じくdaemontoolsに含まれるtai64nlocalで見やすい形式に変換するのがよいでしょう。

$ tai64nlocal < /service/daemon/log/main/current

デーモンが正常に動作しない場合の対処法

最後にdaemontoolsを使用していて実際に遭遇した問題を紹介します。

デーモンがゾンビプロセス化

なんらかの原因でデーモンが異常終了したり、正常に起動しなかった場合、デーモンプロセスがゾンビ化することがあります。daemontools側から見ると正常に動作しているように見えてしまうので、デーモンが正常に動作しているかpsコマンドなどを使って調べてみましょう。特に、異常終了した後に、そのままでは正常に再起動できないようなプログラムをデーモン化している場合は注意が必要です。

superviseがエラーを吐く

supervise: fatal: unable to acquire daemon/supervise/lock: temporary failure

既に指定したデーモンに対してsupervise(もしくはsvscan)が起動していたり、操作ミスなどによりsupervise(もしくはsvscan)自体が異常終了した場合に上記のエラーメッセージが出ることがあります。
この場合、該当するデーモンに対して起動しているsuperviseを終了し(svscanが起動している場合は先にそっちを終了します)、以下のファイルを削除します。

rm /var/daemon/supervise/lock
rm /var/daemon/log/supervise/lock
rm /var/daemon/log/main/lock

追記:(2008/07/24)

一部誤解を与える表現がありましたので、修正しました。

修正箇所

supervise(もしくはsvscan)自体が異常終了した場合に
↓
操作ミスなどによりsupervise(もしくはsvscan)自体が異常終了した場合に

また、lockファイルを削除するよりもいい方法があるようです(コメント
欄参照)。

ご指摘ありがとうございます>fumiyasさん

フォト蔵におけるdaemontoolsの活用例

フォト蔵では今年の7月頃からHyperEstraierによる全文検索を導入したのですが、このHyperEstraierに含まれるestmasterというサーバプログラムの管理にdaemontoolsを活用しています。使い方の一つとしては、estmasterの死活監視があります。estmasterが停止してしまうと検索自体ができなくなってしまいますが、停止してしまってもdaemontools側で自動的に再起動してくれるわけです。


フォト蔵でのHyperEstraierの活用例に関しては、また後日紹介する予定です。


参考ページ

トラックバック

このエントリーのトラックバックURL:
http://www.unoh.net/mt32/mt-tb.cgi/1462

コメント

気になった点を。

「chmod 1755 /var/daemon」が必要なのは古い daemontools だけです。

/var/daemon/run の例が /var/daemon/log/run の内容になっています。

「supervise(もしくはsvscan)自体が異常終了した場合に…」
個人的には svscan も supervise も異常終了した経験ないんですけど、
何かバグがありましたっけ? オペレーションミスで殺してしまった事くらいならありますが、そういうことですか?
あと svscan だけ殺してしまって supervise (とその配下のサービス)
だけが残ってしまった場合は `svc -dx /var/daemon /var/daemon/log` でもどうぞ。
いずれにしても lock ファイルを削除する必要はないと思いましたが。

>fumiyasさん

ご指摘ありがとうございます。

>「chmod 1755 /var/daemon」が必要なのは古い daemontools だけです。

すみません。調査不足でした。追記しました。

>/var/daemon/run の例が/var/daemon/log/run の内容になっています。

すみません。書き忘れていたようです。
修正、追記しました。

>「supervise(もしくはsvscan)自体が異常終了した場合に…」
>個人的には svscan も supervise も異常終了した経験ないんですけど、
>何かバグがありましたっけ? オペレーションミスで殺してしまった事くらいならありますが、そういうことですか?

はい。そうです。紛らわしい書き方ですみません。修正しました。

>あと svscan だけ殺してしまって >supervise (とその配下のサービス)
>だけが残ってしまった場合は `svc -dx /var/daemon /var/daemon/log` でもどうぞ。
>いずれにしても lock ファイルを削除する必要はないと思いましたが。

ありがとうございます。調査不足でした。
本文中のは実際にエラーメッセージが出た時に私がやったことですが、確かにあまりいい方法ではなさそうですね。


コメントを投稿


画像の中に見える文字を入力してください。