现在假设我们正在设计一个应用程序,由2个Erlang节点组成。在节点A上,将有许多进程,数量可能达到数千个。这些进程通过向节点B上的已注册进程发送消息来访问节点B上的资源。
在节点B上,假设您已通过执行以下函数启动了一个进程:
在节点A上,任何想要在节点B上执行给定模块中的任何函数的进程,都会使用以下代码片段:
上述方法可能会增加在节点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上的进程zeemq_server
永远不会停机,并且节点A和B之间的网络连接始终正常,请回答以下问题:
问题1:由于节点B上只有一个接收进程,因此其邮箱很可能一直处于满载状态。这是因为节点A上的进程很多,在给定的时间间隔(例如2秒),每个进程至少向节点B服务器发起一次调用。在哪些方式下,可以使节点B上的接收变得冗余?例如,进程组等,并解释(概念)如何替换上面的服务器端代码。展示客户端侧将会发生什么变化。
问题2:在只有一个接收器在节点B中的情况下,进程邮箱中允许的最大消息数量是多少?如果单个进程邮箱被太多消息淹没,erlang会如何响应?
问题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方面显示为一个名称。这样,传入的消息将在接收器线程之间进行复用,并在这组进程中共享负载。保持问题的含义不变。