Erlang で監視ツールを構築しています。クラスターで実行する場合、すべてのノードで一連のデータ収集機能を実行し、単一の「レコーダー」ノードで RRD を使用してそのデータを記録する必要があります。
現在のバージョンには、マスター ノード ( rolf_node_sup
) で実行されているスーパーバイザがあり、クラスタ内の各ノードで 2 番目のスーパーバイザを実行しようとします ( rolf_service_sup
)。次に、ノード上の各スーパーバイザは、マスター ノードの gen_server にメッセージを送信する一連のプロセスを開始および監視する必要があります ( rolf_recorder
)。
これはローカルでのみ機能します。どのリモート・ノードでもスーパーバイザーは開始されません。次のコードを使用して、レコーダー ノードからノード上のスーパーバイザーをロードしようとします。
rpc:call(Node, supervisor, start_child, [{global, rolf_node_sup}, [Services]])
スーパーバイザーは実際にはローカル プロセス専用に設計されていると示唆する人を何人か見つけました。例えば
クラスター内のすべてのノードで監視されたコードを実行するという私の要件を実装するための最も OTP の方法は何ですか?
- 分散アプリケーションは、分散スーパーバイザ ツリーの代替案の 1 つとして提案されています。これらは私のユースケースには合いません。ノード間のフェールオーバーを提供しますが、一連のノードでコードを実行したままにします。
- プールモジュールは興味深いものです。ただし、すべてのノードではなく、現在最も負荷の低いノードでジョブを実行できます。
proc_lib:spawn_link
別の方法として、各ノードでスーパーバイザを起動するために使用する、監視対象の「プロキシ」プロセスのセット (ノードごとに 1 つ) をマスター上に作成することもできます。ノードで何か問題が発生した場合、プロキシ プロセスは終了し、そのスーパーバイザによって再起動され、リモート プロセスが再起動されます。ここでは、 slaveモジュールが非常に役立ちます。- または多分私は過度に複雑です。ノードを直接監視するのは悪い考えです。代わりに、より疎結合の方法でデータを収集するようにアプリケーションを設計する必要があります。複数のノードでアプリを実行してクラスターを構築し、1 つをマスターに指定して、そのままにしておきます。
いくつかの要件:
- アーキテクチャは、手動で介入することなく、プールに参加したりプールから離れたりするノードに対処できる必要があります。
- 簡単にするために、少なくとも最初はシングルマスターソリューションを構築したいと思います。
- 私の実装では、手巻きのコードよりも既存の OTP 機能を使用したいと考えています。