4

ここで、2つのErlangノードで構成されるアプリケーションを設計していると仮定します。ノードAには、数千のオーダーの非常に多くのプロセスがあります。これらのプロセスは、ノードBの登録済みプロセスにメッセージを送信することにより、ノードBのリソースにアクセスします。

ノードBで、次の関数を実行してプロセスを開始したとします。

start_server()->
    register(zeemq_server,spawn(?MODULE,server,[])),ok.<br>
server()-&gt;
    receive
            {{CallerPid, Ref}, {Module, Func, Args}} -&gt;
                    Result = (catch erlang:apply(Module, Func, Args)),
                    CallerPid ! {Ref, Result},
                    server();
            _ -&gt; server()
    end.

ノードAでは、ノードBの特定のモジュールで関数を実行するプロセスは、次のコードを使用します。

call(Node, Module, Func, Args)-&gt;
        Ref = make_ref(),
        Me = self(),
        {zeemq_server,Node} ! {{Me, Ref}, {Module, Func, Args}},
        receive
                {Ref, Result} -&gt; Result
        after timer:minutes(3) -&gt; 
            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()-&gt;
    register(zeemq_server,spawn(?MODULE,server,[])),ok.<br>
server()-&gt;
    receive
            {{CallerPid, Ref}, {Module, Func, Args}} -&gt;
                    <b>spawn(?MODULE,child,[Ref,CallerPid,{Module, Func, Args}]),</b>
                    server();
            _ -&gt; server()
    end.    
child(Ref,CallerPid,{Module, Func, Args})-&gt;
    Result = (catch erlang:apply(Module, Func, Args)),
    CallerPid ! {Ref, Result},
    ok.

上記の方法では、ノードBで実行されるプロセスの瞬間的な数が増える可能性があり、これはメモリが原因でサービスに大きな影響を与える可能性があります。ただし、見た目は良くserver()、次のリクエストを処理するためにすぐに戻るループになります。この変更についてどう思いますか?

最後に:ノードBにを実装する方法を説明しますが、ノードAに関してはPool of receiver Threads1つになっているように見えますName。これにより、着信メッセージがレシーバースレッド間で多重化され、負荷がこのプロセスグループ内で共有されます。問題の意味を同じにしてください。

4

2 に答える 2

2

プロセス メールボックス内のメッセージの最大数は、メモリの量を除いて無制限です。

また、メールボックスのサイズを調べる必要がある場合は、

erlang:process_info(self(),[message_queue_len,messages]).

これは次のようなものを返します:

[{message_queue_len,0},{messages,[]}]

私が提案するのは、最初に上記のサーバーを gen_server に変換することです。これはあなたの労働者です。

次に、poolboy ( https://github.com/devinus/poolboy ) を使用して、サーバーのインスタンスのプールをプールボーイ ワーカーとして作成することをお勧めします (github Readme.md に例があります)。最後に、プールボーイ トランザクションを作成し、ワーカー引数をプールから関数に適用するヘルパー メソッドを使用して、呼び出し元用のモジュールを作成することをお勧めします。以下の例は、github から引用したものです。

squery(PoolName, Sql) ->
    poolboy:transaction(PoolName, fun(Worker) ->
                                     gen_server:call(Worker, {squery, Sql})
                                  end).

とはいえ、Erlang RPC の方がニーズに適しているでしょうか? Erlang RPC の詳細については、http: //www.erlang.org/doc/man/rpc.html を参照してください。Erlang RPC の適切な処理はhttp://learnyousomeerlang.com/distribunomicon#rpcにあります。

于 2012-11-16T13:10:49.360 に答える