web-dev-qa-db-ja.com

デーモンが起動時に構成ファイルを読み取るのはなぜですか?それらがそのファイル/ホットリロードの変更に「反応」できないのはなぜですか?

構成の変更を有効にするには、デーモンにHUPを送信する必要があることを知っています。しかし、これがなぜなのか、そのような変更に対応するデーモンを作成することが可能であるのかと思っています。

9
Frank Jones

複数の理由があります。主な理由の1つは、多くのデーモンに複数の構成ファイルがあり、単一のファイルの変更はそれ自体では使用できない可能性があるためです。そのため、構成ファイルの変更の1つが解決以上の問題を引き起こす可能性がある場合は常に、デーモンに構成の再読み込みを試行させます。

純粋に実装関連の観点からは、構成ファイルへの変更を監視する必要があるため、デーモンがさらに複雑になります。デーモンにはある種の中心的なループがあり、デーモンの中心的な目的に対応して実行される作業をチェックします。構成ファイルへの変更をチェックすることは、必ずしもその中核的な目的にうまく適合しているわけではありません。

個別のシグナルを処理することで、これらの問題の両方が解決されます。これは、構成が一貫していてリロードしても安全であるとユーザーが考えていることを示し、影響を最小限に抑えながらシグナルハンドラーに非同期で実装できます(通常は基本的なフラグの変更として)。メインループ(フラグの変更に反応します)。

独自の構成変更に反応するデーモンがあります。たとえばcronは、メインループを一周するたびに、構成ファイルの変更をチェックします。

20
Stephen Kitt

他の回答で言及されている他のすべての理由とは別に、より深い、哲学的な理由があり、それは基本的なUnixプログラミング設計原則の1つです:Do One Thing And Do It Well

Unixでは、プログラムは一般に1つのことと1つのことだけを行います。複数のプログラムを組み合わせることで、より複雑な操作を実現します。

さて、(例えば)ウェブサイトを提供することは一つのことです。ファイルの変更を監視すること、それは別のことです。したがって、Unixのモットーによれば、これらは2つの異なるプログラムである必要があります。 Webサイトにサービスを提供および変更が行われていないことをファイルで監視One Thing And Do It Well、それは2つのことを実行します。そして、2つのことを非常に頻繁に行うプログラムは、これら2つのことの少なくとも1つをあまりうまく実行しません。 (たとえば、Webサーバーを作成した人は、HTTPの専門家であっても、ファイル監視の専門家ではない可能性があります。)

具体的には、ネットワークに接続するデーモンの場合、Do One Thingのマントラを守るためのもう1つの理由、セキュリティがあります。コードのすべての1行は潜在的なバグです。最も安全なコードはコードなしです。そこに属さない責任をデーモンから削除することにより、コードの量を削減し、攻撃面を減らすことができます。

複数のことを行うプログラムがそれらの複数のことの少なくとも1つを頻繁に行うことが多いという事実とは別に、責任を分割する別の理由があります:コードの再利用 。ファイル監視がWebサーバーの一部である場合、SSHサーバーもファイル監視を実装する必要があります。そしてあなたのファイルサーバー。そしてあなたのチャットサーバー。そしてあなたのテレフォニーサーバー。そしてあなたのデータベースサーバー。そしてあなたのメディアストリーミングサーバー。などなど。

一方、ファイル監視が別のプログラムの責任である場合、このプログラムを実装する必要があるのは1回、1回のテスト、1回の最適化、1回の文書化などです。 。また、使用方法を1回トレーニングするだけで、これまでに作成されたすべての単一デーモンに適用でき、実際に将来書き込まれるすべての単一デーモン

したがって、if質問で質問したいことを実行したい場合、twoデーモン:たとえば、 Webサイトを提供し、ファイルの変更を監視し、それらの変更に基づいてアクションを実行するサイト。

そして、それはおそらく驚くべきことではありません、そのようなデーモンはすでに存在しています。

8
Jörg W Mittag

他の回答への追加:最大の障害の1つは、各構成値に、少なくともアプリケーションの現在の状態、以前の値、および他の値の変更を認識できる解釈を要求することです。一般に、設定ファイルはデーモンに非実行状態から初期状態に移行する方法を指示します。デーモンが構成を変更時に再ロードするということは、構成値をデーモンの現在の状態への変更として解釈できることも意味します。たとえば、ある種のタスクデーモンについて考えてみましょう。その構成ではworker_threads: 2になります。デーモンが起動したばかりの場合、解釈は簡単です。タスクを実行するために2つのスレッドを作成します。その値の変更を処理する必要がある場合は、複数のことを実行する必要があります。スレッド数が増加した場合は、スレッドを追加します。減少している場合は、スレッドをいくつか削除してください。

変更の解釈は以前の値に依存するだけでなく、デーモンの現在の状態にも依存します。設定をworker_threads: 1に更新した場合、両方のスレッドが使用されている場合、デーモンは何をする必要がありますか? configに記述されている状態とすぐに一致するように殺す必要がありますか?タスクの実行を完了してから、1つのスレッドを強制終了する必要がありますか?

それ以降、設定値の変更の解釈は、変更された他の設定値にも依存します。すべてのワーカーが使用されているときにワーカースレッドの数を減らすときに何をすべきかを決定する追加の構成値があるとします:kill_threads_on_worker_reduction: true/false。これが設定されていれば、アクティブなワーカースレッドを強制終了するかどうかを決定できます。しかし、その構成値がalsoに変更された場合はどうなりますか?実行中の新しいタスクにのみ適用されますか、それとも変更前に開始されたタスクに遡及的に適用されますか?

これはone可能な設定値にドリルダウンするだけです。すべての構成値、考えられるすべてのアプリケーション状態、および変更された値の考えられるすべての組み合わせについて、これを把握する必要があります。

確かに、設定変更の解釈がはるかに簡単な場合もありますが、これは、設定のライブ再読み込みが一般的に簡単に実行できないものではない理由を説明するのに役立ちます。

0
mowwwalker