(明らかに、この問題は非常にエキゾチックですが、「内部にどのように配置されるか」という点では非常に有益です。)それで、Erlangで書かれたアプリケーション(たとえば、同じejabberd)があるとします。 それは長い間機能しており、うまく機能していますが、ある日、制御スクリプト(それぞれejabberdctl)を実行しようとしています。そして、「nodedown」またはこの精神で恐ろしい何かを提供します、彼らは誰も応答しません。 同時に、アプリケーション自体はすべてのクライアント要求に完全に応答し、ダウンしていることを聞いたことはありません。 突然の
epmd -names
、
epmd -names
と-ああ、ホラーを実行します! -空のリストを取得します。
Erlangプログラムは
node@host
表記を使用して相互に通信しますが、物理的に各ノード(システムプロセスを読み取る)は、このためにランダムに高いポートを開きます。
epmd
サービスのタスクは、名前による論理アドレス指定とポート番号による物理アドレス指定を接続することです。
epmd
レジストリがなければ、
epmd
上のクラスターは、
epmd
の別個の聴覚障害者ミュートノードにバラバラになるという違いがありますが、何らかの謎の理由で発生しました。 もちろん、責任者を探し始めることもできますが、最初はシステムを所定の場所に持ち上げることをお勧めします。
そのような状況で何をすべきか? もちろん、アプリケーションを強制的に再起動することもできますが、一方で、クライアントは落ちてしまいます。一方で、このような美しいアップタイムは残念です...さて、どういうわけかライブシステムでレジストリを復元できるとしたら?..
恐れるな! インターネットで発掘された情報の
epmd
、
epmd
1つの正しいパッケージをスローするのに十分で
epmd
と思われると報告しています。 たとえば、Cに簡単なプログラムを追加します。まあ、低レベルに移動する必要はありません。ソケットとErlang自体でうまく動作しますが、もっと簡単にしたいです。 私がしたい-お願い:erl_epmdモジュールに遭遇し、その中を見てください-オープンソースに栄光を! -ホスト名とポート番号を取得するマジック関数
register_node/2
。
netstat
を使用して、アプリケーションで使用されているポートを確認し(23456とします)、ターミナルでエミュレータを実行します。
$ erl
ノードは匿名である必要があります。これは、手動で名前を登録するためです。これ(同じ
erl_epmd
コードを参照)は、起動ごとに1回しか実行できません。
> erl_epmd:start().
...しかし、サイトはまだ匿名であるため、最初に手で遺伝子サーバーを起動する必要があります。 次に、魔法の関数を呼び出します。
> erl_epmd:register_node( ejabberd, 23456 ).
これで、失われたノードと再び通信できます。 確認するには、
epmd -names
実行
epmd -names
、喜んで...
だから、やめて、私たちは幸せではありません。
epmd
は、earlが使用する任意のポートで任意の名前の登録を質問なしで受け入れますが、この登録要求がどの接続から来たかを覚えており、接続が
epmd
とすぐに名前が再び解放されます。 したがって、システムを正しく動作させるには、不要な一時エミュレータを実行したままにしておく必要があります。 混乱? 混乱。 どういうわけかアプリケーションの内部に入り、そこから
register_node
を呼び出す必要があります...
エレメンタリー、ワトソン(既に知っている場合)。 今回は、2番目のエミュレータを起動します。名前は次のとおりです。
$ erl -sname repair
...アプリケーションでノードにpingを実行します。
repair@hostname> net_adm:ping( ejabberd@hostname ).
(ピンポンを手に入れた場合、すべては計画通りです。パンを手に入れたら、役に立たなくなった記事を閉じて、部屋の周りで叫び始めます。)
そして今、トリック。 それは、確立されたノード間の接続が確立されたままであるという事実にあります-私たちはちょうどそれを行いました-さらに通信を行うために
epmd
レジストリ
epmd
もはや必要
epmd
ません。 そのため、最初のエミュレーターに戻ってネイルします。
> halt().
今何をしましたか? とりわけ、
epmd
への接続を
epmd
、彼は
ejabberd
という名前を再登録のために解放しました。 (信じられない場合は、
epmd -names
もう一度見てください。)
これで、オープン接続が保険なしで天井にぶら下がったまま、優れた
rpc
モジュールを使用して、アプリケーションノードに移動し、3つのプロセスで同時ゲームのセッションを見事に終了できます。
repair@hostname> rpc:call( ejabberd@hostname, erl_epmd, register_node, [ejabberd, 23456] ).
repair@hostname> halt().
そして口ひげ。 ターミナルを閉じ、最初にシステムに登ったことを行います。
質問、説明、修正を歓迎します。