私のnginxユニットファイルは次のとおりです。
[root@arif ~]# cat /usr/lib/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
ここでこの[Service]
セクションでの値は次Type
のとおりです。forking
ここ、
ExecStartで始まるプロセスは、サービスの基本プロセスとなるサブプロセスを作成します。開始が完了すると、親プロセスが終了します。
私の質問は、
- サービスがなぜこのようなことをするのか?
- これにはどのような利点がありますか?
Type=simple
それとも、他の同様のオプションにはどのような問題がありますか?
答え1
サービスがなぜこのようなことをするのか?
平均サービス欲しくない実際にそうしてください。これは良い習慣ではなく、「デーモン」の考えが実際に間違っているという事実に加えて、サービスは何をすることができますか?forking
契約によって要求されない。彼らが実際にやっていたことからプロトコルが間違っていました。その他、これはforking
プロトコルに含まれており、通常は不要です。
これにはどのような利点がありますか?
いいえ。より良いコントラスト通知プロトコルが存在しますが、実際に話す人はいません。これプロトコルは正しいです。そうするのが有利なので、サービスはそうしません。
Type=simple
それとも、他の同様のオプションにはどのような問題がありますか?
何もありません。実際、一般的に言えば、準備プロトコルはforking
誤って使用されます。他の答えで述べたように、これはベストプラクティスではありません。正反対。
単純な事実は、それが悪いことの最善であり、nginxのまだブロックできない行動からの避難所であるということです。今日、IBM SRC、daemontools、およびその他の深刻なサービス管理の分野での励ましのおかげで、ほとんどのサービスソフトウェアにはオプションがあり、さらに基本的な動作も変更され、もはや愚かなことを「デーモン化」しようとしません。すでにデーモンのコンテキストにあります。
しかし、nginxの場合はまだそうではありません。 daemon off
残念ながら動作しません。多くのソフトウェアが「ビデモン」モードをデバッグモードと誤って混同したように(しかし一般的にこれ以上そうしない)、nginxは残念ながら制御信号を処理しないなど他のものと混同します。これまで人々はこの仕事を5年間やってきました。
追加読書
- ジョナサンデボインポラード(2015)。Unixデーモンの準備プロトコルの問題。よく与えられる答えです。
- エイドリアン・クレア(2013-10-27)。
type=forking
nginx:systemdサービスファイルには使用しないでください。 Debianのバグ#728015。 - ランイットとnginx
- ジョナサン・ドボイン・ポラード(2001)。 」「デーモンを背景に置く」ためだけにfork()を使用しないでください。」。 Unixデーモンを設計する際に避けるべき間違い。よく与えられる答えです。
- ジョナサンデボインポラード(2015)。実際にデーモンは必要ありません。本当。。体系化された恐怖の家。
- StackExchange には準備プロトコルの不一致の例がたくさんあります。
- https://unix.stackexchange.com/a/401611/5132
- https://unix.stackexchange.com/a/200365/5132
- https://unix.stackexchange.com/a/194653/5132
- https://unix.stackexchange.com/a/211126/5132
- https://unix.stackexchange.com/a/336067/5132
- https://unix.stackexchange.com/a/283739/5132
- https://unix.stackexchange.com/a/242860/5132
答え2
systemdが初期化を完了した後に関連サービスがメッセージングを具体的にサポートしていない限り(参考文献を参照man systemd-notify
)、フォーク方法は従来の通知方法として使用されます。 systemdによって報告されたサービス状態は、親プロセスが存在する限り維持されsystemctl status
ますstart
。親プロセスが終了した後にのみ
変更されます。running
既存のデーモンサービスの親プロセスは、子プロセスが設定を完了して使用可能になった後にのみ終了します。
関連サービスの使用準備が整うのを待つ依存サービスがある場合は、このメカニズムが必要です。特定の通知方法をサポートしていないサービスを開始するために既存のデーモンブランチメカニズムを使用しない場合、systemd
サービスの状態はrunning
即座に変更され、関連サービスを使用する準備ができる前にすべての依存サービスがすぐに開始されます。
この理由はで詳細に説明されています。Debian のバグ #728015これはすでにJdeBPの答えにリンクされています。
これはバグが閉じられた理由でもありますwontfix
。