ここで、2つのErlangノードで構成されるアプリケーションを設計していると仮定します。ノードAには、数千のオーダーの非常に多くのプロセスがあります。これらのプロセスは、ノードBの登録済みプロセスにメッセージを送信することにより、ノードBのリソースにアクセスします。
ノードBで、次の関数を実行してプロセスを開始したとします。
start_server()->
register(zeemq_server,spawn(?MODULE,server,[])),ok.<br>
server()->
receive
{{CallerPid, Ref}, {Module, Func, Args}} ->
Result = (catch erlang:apply(Module, Func, Args)),
CallerPid ! {Ref, Result},
server();
_ -> server()
end.
ノードAでは、ノードBの特定のモジュールで関数を実行するプロセスは、次のコードを使用します。
call(Node, Module, Func, Args)->
Ref = make_ref(),
Me = self(),
{zeemq_server,Node} ! {{Me, Ref}, {Module, Func, Args}},
receive
{Ref, Result} -> Result
after timer:minutes(3) ->
error_logger:error_report(["Call to server took so long"]),
{error,remote_call_failed}
end.
したがって、ノードBのプロセスがダウンすることはなく、ノードAとノードBの間のネットワーク接続が常にアップしていると仮定してzeemq_server
、次の質問に答えてください
。Qn 1:ノードBには受信プロセスが1つしかないため、そのメールボックス常に満員である可能性が最も高いです。これは、プロセスがノードAに多数あり、特定の間隔、たとえば2秒で、少なくともすべてのプロセスがノードBサーバーに対して1回の呼び出しを行うためです。どのようにして、ノードBで受信を冗長化できますか?たとえば、プロセスグループなどで、これが上記のサーバー側コードをどのように置き換えるかを説明します(概念)。クライアント側でどのような変更が行われるかを示します。
Qn 2:ノードBに受信者が1つしかない状況で、プロセスメールボックスで許可されるメッセージの最大数はありますか?単一のプロセスのメールoxがあまりにも多くのメッセージで溢れている場合、erlangはどのように応答しますか?
Qn 3:どのようにして、上記の概念を使用して、要求を送信するすべてのプロセスが、タイムアウトが発生する前にできるだけ早く応答を返すことを保証できますか?ノードBの受信部分を並列操作に変換することは役に立ちますか?このような:
start_server()->
register(zeemq_server,spawn(?MODULE,server,[])),ok.<br>
server()->
receive
{{CallerPid, Ref}, {Module, Func, Args}} ->
<b>spawn(?MODULE,child,[Ref,CallerPid,{Module, Func, Args}]),</b>
server();
_ -> server()
end.
child(Ref,CallerPid,{Module, Func, Args})->
Result = (catch erlang:apply(Module, Func, Args)),
CallerPid ! {Ref, Result},
ok.
上記の方法では、ノードBで実行されるプロセスの瞬間的な数が増える可能性があり、これはメモリが原因でサービスに大きな影響を与える可能性があります。ただし、見た目は良くserver()
、次のリクエストを処理するためにすぐに戻るループになります。この変更についてどう思いますか?
最後に:ノードBにを実装する方法を説明しますが、ノードAに関してはPool of receiver Threads
1つになっているように見えますName
。これにより、着信メッセージがレシーバースレッド間で多重化され、負荷がこのプロセスグループ内で共有されます。問題の意味を同じにしてください。