Python でデーモンを作る
デーモンには幾つかの決まりごとがあるが、それさえ判っていればスクリプトなどでも作成できる。
そこで今回は、Python でデーモンを作る方法を説明する。
デーモンに必要な事
デーモンには幾つかの決まり事がある。その基本的な事を説明する。
デーモンは勝手に終了してはいけない
デーモンはサービスを提供する存在なので、基本的に常に待機状態である必要がある。
また、SIGTERM を受信した場合は、速やかに終了する事が望ましい。
そのため、構造的には無限ループで処理待ちにして、UNIX シグナルを受信する構造が望ましい。
※ マシンの終了時や再起動時には SIGTERM がカーネルから発信される。
設定は設定ファイルで行う
プログラムに埋め込まれたパラメータは少なめにし、多くのパラメータは設定ファイルに記載するのが望ましい。
また、SIGHUP を受信した場合は、設定ファイルの再読み込みを行うのが望ましい。
※ 「systemctl reload ユニット名」では、SIGHUP が受信される。
Python で利用するモジュール
設定ファイルの読み込み
「ConfigParser」設定ファイルを読み込んで解析し、ディクショナリとして利用できる。
UNIX シグナルの受信
「signal」UNIX シグナルを受信し、それぞれに対応した処理を行う。
※ 通常はココに書いてある通りに、signal.signal(signal.SIGHUP, 関数)、signal.signal(signal.SIGTERM, 関数) の処理を書く事になる。
処理をデーモン化
リクエストに従って、処理をフォークする必要がある場合は「multiprocessing.Process:Process
クラスと例外」を使用する。
だたし処理を投げっ放し(joinしない場合など)では「daemon」フラグを「True」にしておく必要がある。 これをしておかないと、join 待ちのスレッドが大量に生成される事になる。
Python プログラムでの決まり事
コマンドとして実行可能にする
「#!/usr/bin/env python」を先頭行に書いておき、Python スクリプトとして実行可能にしておく。コレを記載しておくと、拡張子を省略する事が可能になる。
「if name == ‘main’:」を記載しておいて、メインの存在を明確にしておく。
「chmod +x」で実行権を付与しておく。
よく使われるトラップ
「/usr/libexec」や「/usr/local/libexec」に拡張子「.py」が付いた状態でファイルを保存しておき、シンボリックリンクを「/usr/bin」や「/usr/local/bin」に拡張子なしで保存しておく。
サービスファイルの作成
サービスファイルを作成しておくと、「systemd」に対応する事が可能になる。
「/usr/lib/systemd/system」に保存しておく必要がある。
サービスファイルの作成例
「daemon.service」
[Unit] Description = 説明文 [Install] WantedBy = multi-user.target #通常はこのまま [Service] ExecStart = /usr/local/bin/deamon #実行するファイル Restart = yes #勝手に終了した場合は、再起動させる Type = simple #通常はこのまま
起動設定
「systemctl enable daemon」 デーモンの自動起動
「systemctl start daemon」 デーモンの起動
「systemctl stop daemon」 デーモンの停止
「systemctl status daemon」 デーモンの状態取得
参考
「10.6. systemd のユニットファイルの作成および変更」