web-dev-qa-db-ja.com

特定のアプリケーションに使用するsystemdサービスの「タイプ」を決定する方法

Systemdを構成できるさまざまなTypeのサービス(たとえば、simpleoneshotなど)を比較的うまく処理できると思います。

docs は、オプションのかなり合理的な概要と説明を提供します。そのため、多くの場合、最善の選択肢を「推測」し、「試行錯誤」して確認することができます。これは特に、私がよく知っているアプリケーションの場合です。

ただし、「試行錯誤」のテスト中に考慮していない状況が発生する可能性があることを懸念しています(つまり、エッジケースのバグのリスク)。だから私は、アプリケーションをテスト/調査して、それがおそらく最良のTypeであると判断する方法についての提案を求めています。

FWIW、アプリケーションを手動で起動し、フォークするかどうか(複数のプロセスなど)にアプリケーションがどのように応答するかを追跡する方法を考えています。 (標準のコマンドラインツールを使用して)それを行うための比較的簡単な方法がないに違いないと思います。

関連性があるかどうかはわかりませんが、Debianが私の選択したディストリビューションです。

5
Jeremy Davis

(からコピー Super User.SEに関する私の回答

コマンドラインから手動でサービスを開始する場合(Nohupprefixコマンドまたは&サフィックスを使用せずにバックグラウンドで実行するか、言い換えると、コマンドラインのExecStart=行に配置するコマンドを実行するだけです。 .serviceファイル)、どうなりますか?

a)サービスが開始して実行を続け、Control-Cを押すか、他の方法でサービスを停止するまでプロンプトが戻らない場合:then Type = simpleが正しい選択です。

b)プロンプトが戻ってもサービスがバックグラウンドで実行され続ける場合(つまり、サービスがそれ自体をデーモン化する場合)、Type = forkingが正しい選択です。

c)サービスがジョブを実行し、何も実行せずにプロンプ​​トに戻った場合(つまり、サービスがカーネル設定を調整するだけで、コマンドを何かに送信しますそれ以外の場合、または同様のことを行う場合)、Type = oneshotがおそらく正しい選択です。この場合、サービスのExecStartは何かを「設定」するコマンドであり、ExecStopはそれを「設定解除」する対応するコマンドです。このタイプは通常RemainAfterExit=trueの利点があるため、systemdは、最近「設定」されたか「未設定」かに従って、このサービスの「状態」を追跡します。

他のType値は特殊なケースです。たとえば、サービスがD-Bus接続を利用している場合、Type = dbusが最良の選択である可能性があります。 systemdに事実を認識させ、systemdはD-Busにこのサービスが存在することで、このサービス(およびそれに依存するすべてのもの)を追跡します。

Type = notifyを使用するには、プロセスが環境変数$NOTIFY_SOCKETで指定されたUnixソケットに接続し、必要に応じてそのソケットにメッセージを書き込んでステータスを報告できる必要があります。また、サービスファイルでは、NotifyAccessオプションを指定して、通知ソケットへのアクセスを適切に許可する必要があります。

これらのメッセージの送信に使用できるコマンドラインユーティリティsystemd-notifyとCライブラリ関数sd_notify(3)がありますが、どちらも要件に適していない場合は、独自のメッセージ送信者を実装できます。必要なメッセージは非常に単純で、シェル変数の割り当てのように見えます。たとえば、サービスが正常に起動を完了し、着信要求を処理する準備ができていることを通知するには、サービスはprintf "READY=1\n"の出力に相当する文字列をソケットに送信する必要があります。認識されるメッセージの詳細については、man 3 sd_notifyを参照してください。

注:多くのUnixスタイルのシステムに移植できるように設計された多くのサービスアプリケーションは、デフォルトでb)として動作する可能性がありますが、オプションを追加することでa)のように動作させることができます(通常は「フォークしない」、「実行を続ける」フォアグラウンドで」、「デーモン化しないでください」など)。その場合、オプションに他の副作用がない場合は、オプションを追加し、a)タイプの動作を使用することをsystemdに推奨します。

9
telcoM