现在,假设我们正在设计一个应用程序,由 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.
所以假设zeemq_server
Node B上的进程永远不会down,并且Node A和B之间的网络连接一直是up的,请回答以下问题:
Qn 1:由于Node B上只有一个接收进程,它的邮箱最有可能是满的,一直。这是因为,节点 A 上的进程很多,并且在给定的时间间隔内,例如 2 秒,每个进程至少对节点 B 服务器进行一次调用。可以通过哪些方式使节点 B 上的接收变得冗余?,例如进程组等并解释(概念)这将如何替换上面的服务器端代码。显示客户端会发生什么变化。
Qn 2: 在节点 B 上只有一个接收者的情况下,进程邮箱中允许的最大消息数是多少?如果单个进程邮件牛被太多消息淹没,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.
如上所示的方法,可能会增加Node B上运行的瞬时进程数,这可能会因内存而对服务造成很大影响。但是,它看起来不错,并使server()
循环立即返回以处理下一个请求。您对此修改有何看法?
最后:说明您将如何Pool of receiver Threads
在节点 B 上实现 a,但在节点 A 上似乎低于一个Name
。这样,传入消息在接收线程之间多路复用,并且在这组进程中共享负载。保持问题的含义相同。