救急蘇生epmd

(明らかに、この問題は非常にエキゾチックですが、「内部にどのように配置されるか」という点では非常に有益です。)

それで、Erlangで書かれたアプリケーション(たとえば、同じejabberd)があるとします。 それは長い間機能しており、うまく機能していますが、ある日、制御スクリプト(それぞれejabberdctl)を実行しようとしています。そして、「nodedown」またはこの精神で恐ろしい何かを提供します、彼らは誰も応答しません。 同時に、アプリケーション自体はすべてのクライアント要求に完全に応答し、ダウンしていることを聞いたことはありません。 突然のepmd -namesepmd -namesと-ああ、ホラーを実行します! -空のリストを取得します。

Erlangプログラムはnode@host表記を使用して相互に通信しますが、物理的に各ノード(システムプロセスを読み取る)は、このためにランダムに高いポートを開きます。 epmdサービスのタスクは、名前による論理アドレス指定とポート番号による物理アドレス指定を接続することです。 epmdレジストリがなければ、 epmd上のクラスターは、 epmdの別個の聴覚障害者ミュートノードにバラバラになるという違いがありますが、何らかの謎の理由で発生しました。 もちろん、責任者を探し始めることもできますが、最初はシステムを所定の場所に持ち上げることをお勧めします。

そのような状況で何をすべきか? もちろん、アプリケーションを強制的に再起動することもできますが、一方で、クライアントは落ちてしまいます。一方で、このような美しいアップタイムは残念です...さて、どういうわけかライブシステムでレジストリを復元できるとしたら?..

恐れるな! インターネットで発掘された情報のepmdepmd 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().

そして口ひげ。 ターミナルを閉じ、最初にシステムに登ったことを行います。

質問、説明、修正を歓迎します。

Source: https://habr.com/ru/post/J49535/


All Articles