systemd
私は非常に長い間実行されるコマンド1(時間単位で測定)を管理するために独自のユニットファイルを作成したいと思います。検索中systemdに関するArchWiki記事、開始タイプの選択について、次のように説明します。
Type=simple
(デフォルト):systemdはサービスがすぐに開始されると見なします。プロセスは分岐してはいけません。。このサービスに対して別のサービスを注文する必要がある場合は、ソケットがアクティブでない限り、このタイプを使用しないでください。
なぜフォークをまったく処理できないのですか?デーモンがプロセスを呼び出す方法(親フォーク後に終了)でフォークを意味しますか、それともどのようなフォークを意味しますか?
1 tmux/screenに依存せずに状態を確認し、サービスを再起動するよりエレガントな方法が必要なので、tmux/screenは不要ですtmux send-keys
。
答え1
サービスがfork
システムコールを実行できるようにします。 Systemdはこれをブロックせず、ブロックしてもそれを認識しません。この文は、特にデーモンプロセスを親プロセスから分離するためにデーモンプロセスの先頭から分岐する慣行を表します。 「プロセスは、[サブプロセスでサービスが実行されている間に親プロセスを終了して]分岐しないでください。」
これマニュアルページこれについては、より詳細に説明し、これらの特別な混乱を引き起こさない表現として説明します。
デーモンとして使用される多くのプログラムには、起動時に親プロセスから自分自身を分離するモード(通常はデフォルトモード)があります。デーモンが起動し、呼び出された後に親fork()
プロセスが終了します。子プロセスはそれを呼び出してsetsid()
独自のプロセスグループとセッションで実行し、サービスを実行します。その目的は、シェルコマンドラインからデーモンを呼び出すと、端末に何が起こっても(たとえば、端末を閉じる)、デーモンがカーネルやシェルから信号を受け取らないことです(この場合、シェルはすべてのプロセスグループを知っています)ターミナルにSIGHUPを送信します。これにより、サービスプロセスがinitによって採用され、終了時にそれを収集して次のことを防ぎます。ゾンビデーモンが不適切なものによって開始された場合wait()
(デーモンがシェルによって開始された場合、これは起こりません)。
systemdのような監視プロセスによってデーモンが起動されると、フォークは非生産的です。サービスがクラッシュした場合、監視プロセスはサービスを再起動する必要があるため、サービスが終了したかどうかを知る必要があります。サービスが監視プロセスの直接的なサブアイテムではない場合、これは困難です。監視プロセスは永遠に消えてはいけません。制御する端末がないため、不要な信号やハーベストを心配する必要はありません。したがって、サービスプロセスがモニターの子プロセスにならない理由はなく、そうするのに十分な理由があります。
答え2
このArch Wikiページを無視してください。
設定にかなり大きなバグがありますType
。そしてそれは説明に限定されませんsimple
。言う内容もforking
間違っていました。
この種の仕事に対する良いアドバイスは何十年も存在しており、systemd自体よりも古く、少なくとも1990年代初頭にさかのぼります。私がそうしたようにhttps://unix.stackexchange.com/a/476608/5132、systemd docoの最新バージョンに対するJohnnyのデーモンの提案がありますが、これはdaemontoolsユーザー、IBM、を使用している人inittab
、そして...まあ...私が何十年も言ってきたことの多くを繰り返します。 (2001年私がこの質問を書いた当時はすでによく出てくる答えでした。)
繰り返す:
プログラムに一種の「デーモン」メカニズムがある場合、特にサブプロセスをフォークして親プロセスを終了する場合、オフそして使用しないでください。 daemontoolsなどに感謝します。これが長い間要求されていた部分では、多くのプログラムが次の機能を強化しました。いいえこれらのメカニズムは過去20年以上存在してきましたが、他のメカニズムはもともと「デーモン」にデフォルト設定されていないため、デフォルトの動作モードで使用できました。
サービス管理サブシステムがサービスプロセスを開始します。すでにデーモンのコンテキストにあります。これらのプロセスには「デーモン」は必要ありません。 (実際には多くの最新のオペレーティングシステムでは、プログラムはできるログインセッションのコンテキストでは、「dæmonize」は「dæmonization」が実際に意味するものです。 ) 彼らはすでにデーモンコンテキストに適した環境値とオープンファイル記述子を持っており、実際に「デーモン化」が実行するいくつかのタスクがあります。止めるサービス管理者は定期的にデーモンを使用して、いくつかの一般的な操作(標準出力/エラーをログに取り込む)を実行します。
を好みType=simple
、あらかじめソケットを開きます(サービスマネージャはサーバーソケットを開き、それを開いたファイル記述子としてサービスプログラムに渡します)Type=notify
。
Type=simple
サービスプロセスが開始されるとすぐに、サービスは準備完了と見なされ(注文されたサービスが開始/停止されるように)、クライアントサービスを延期するためにクライアントがサーバーに接続しようとしている間、できるだけ早くソケットが開きます。 。サーバーが実際に準備されるまでサービスを提供します。Type=notify
systemdとLinuxには特定の欠点があります(シェル生成などの短期プロセスでは機能できない、パーサーの問題を持つ特権systemd-notify
プロセスで人間が読める形式をマシンが読める形式に解析する問題を含む)。それが起こった過去)、しかし、サービスが実際に準備されたと見なされる時点について(サービスプログラムの観点から)より詳細な制御を提供するという利点がある。ステータス出力を一部カスタマイズすることもできます。
どちらのタイプのサービスプログラムも分岐できます。それはフォークですその後、元のプロセスを終了します。それが問題だ。
(シェルでプログラムを実行することは、サービスマネージャでプログラムを実行するのと同じくらい問題があることに注意する必要があります。 . シェルから親を分岐して終了するプログラムを実行します。時々端末でプログラムを実行しても端末で実行されないのはなぜですか?.)
Type=oneshot
この特別なケースでは、サービスプログラム全体が実行され、完了したときにのみサービスが準備されたと見なされるので、望むものではないかもしれません。用途がありますが、お客様に適用されるとは限りません。
使用しないでくださいType=forking
。手続きがほとんどないので、最後の手段になるはずです。実際、合意は。彼らは中にいるその他、これは実際にいいえこのプロトコルはこのプロトコルと正しく相互運用されておらず、実際に準備状態を通知しません。
追加読書
- ジョナサン・ドボイン・ポラード(2001)。 Unixデーモンを設計する際に避けるべき間違い。一般的な答え。
- ジョナサンデボインポラード(2015)。実際にデーモンは必要ありません。本当。。体系化された恐怖の家。
- ジョナサンデボインポラード(2015)。Unixデーモンの準備プロトコルの問題。よく与えられる答えです。
- https://unix.stackexchange.com/a/401611/5132