Multithreading Erlang节点到节点消息传递吞吐量、超时和保证
现在,假设我们正在设计一个由2个Erlang节点组成的应用程序。在节点A上,将有成千上万个进程。这些进程通过向节点B上已注册的进程发送消息来访问节点B上的资源。Multithreading Erlang节点到节点消息传递吞吐量、超时和保证,multithreading,erlang,Multithreading,Erlang,现在,假设我们正在设计一个由2个Erlang节点组成的应用程序。在节点A上,将有成千上万个进程。这些进程通过向节点B上已注册的进程发送消息来访问节点B上的资源。在节点B上,假设通过执行以下函数启动了一个进程: start_server()- 注册(zeemq_服务器,spawn(?模块,服务器,[]),正常。 服务器()- 接收 {{CallerPid,Ref},{Module,Func,Args}- 结果=(catch erlang:apply(模块、函数、参数)), 呼叫者ID!{Ref,R
在节点B上,假设通过执行以下函数启动了一个进程:
start_server()-
注册(zeemq_服务器,spawn(?模块,服务器,[]),正常。
服务器()-
接收
{{CallerPid,Ref},{Module,Func,Args}-
结果=(catch erlang:apply(模块、函数、参数)),
呼叫者ID!{Ref,Result},
服务器();
_-server()
结束。
在节点A上,想要在节点B上的给定模块中执行任何功能的任何进程都使用以下代码段:
调用(节点、模块、函数、参数)-
Ref=make_Ref(),
Me=self(),
{zeemq_服务器,节点}!{{Me,Ref},{Module,Func,Args},
接收
{Ref,Result}-Result
计时器后:分钟(3)-
错误记录程序:错误报告([“对服务器的调用花费了很长时间]),
{错误,远程调用失败}
结束。
因此,假设节点B上的Processzeemq_server
永远不会关闭,并且节点A和B之间的网络连接始终处于打开状态,请回答以下问题:问题1:因为节点B上只有一个接收进程,所以它的邮箱很可能一直都满了。这是因为,节点A上的进程很多,并且在给定的间隔(例如,2秒)内,每个进程至少对节点B服务器进行一次调用。哪种方式可以使节点B上的接收成为冗余,e、 g.处理小组e.t.c.并解释(概念)这将如何取代上述服务器端代码。显示客户端将发生的更改。
问题2:在节点B上只有一个接收者的情况下,流程邮箱中是否有允许的最大消息数?如果单个进程的邮件箱中充斥着太多的消息,erlang将如何响应
问题3:使用上述概念,我可以通过什么方式保证每个发送请求的进程在超时发生之前尽快得到响应?将节点B上的接收部分转换为并行操作是否有帮助?像这样:
start_server()-
注册(zeemq_服务器,spawn(?模块,服务器,[]),正常。
服务器()-
接收
{{CallerPid,Ref},{Module,Func,Args}-
spawn(?MODULE,child,[Ref,CallerPid,{MODULE,Func,Args}]),
服务器();
_-server()
结束。
子(Ref,CallerPid,{Module,Func,Args})-
结果=(catch erlang:apply(模块、函数、参数)),
呼叫者ID!{Ref,Result},
好啊
上面显示的方法可能会增加节点B上运行的进程的瞬时数量,这可能会由于内存而对服务产生很大影响。但是,它看起来不错,并使server()
循环立即返回以处理下一个请求。你对这次修改有什么看法最后:举例说明如何在节点B上实现一个接收方线程池,但在节点a上似乎位于一个
名称下。这样,传入消息在接收方线程之间进行多路传输,并在这组进程中共享负载。保持问题的含义不变。
进程邮箱中的最大邮件数是无限的,除了内存量
此外,如果需要检查邮箱大小,请使用
erlang:process_info(self(),[message_queue_len,messages]).
这将返回如下结果:
[{message_queue_len,0},{messages,[]}]
我建议您首先将上面的服务器转换为gen_服务器。这是你的工人
接下来,我建议使用poolboy()创建一个作为poolboy工作者的服务器实例池(在他们的github Readme.md中有一些示例)。最后,我建议使用一个helper方法为调用方创建一个模块,该方法创建一个poolboy事务,并将池中的Worker arg应用于函数。下面的示例来自他们的github:
squery(PoolName, Sql) ->
poolboy:transaction(PoolName, fun(Worker) ->
gen_server:call(Worker, {squery, Sql})
end).
也就是说,Erlang RPC能更好地满足您的需求吗?有关Erlang RPC的详细信息,请访问。Erlang RPC的一个很好的处理方法是在 IMO生成一个新流程来处理每个请求可能有些过分,但如果不知道每个请求都要做些什么,就很难说了
您可以有一个处理每个消息的进程池,使用循环方法分发请求,或者根据请求类型处理请求,将其发送到子进程或生成一个进程。您还可以通过查看池进程的msg队列并在重载时启动新的子进程来监视池进程的负载。使用主管。。只需在init中使用send_after,每隔几秒钟监控一次负载并相应地采取行动。如果可以,使用OTP,虽然有开销,但值得
我不会使用http进行专线通信,我相信这会带来太多的开销。您可以使用一组进程来控制负载。这与java有关吗?没有得到太多的答案,您不介意我问一下,最后做了什么?