现在,假设我们正在设计一个应用程序,由2个Erlang节点组成。在节点A上,将有很多进程,数千个订单。这些进程通过向节点B上的已注册进程发送消息来访问节点B上的资源。
在节点B,假设您通过执行以下函数启动了进程:
start_server()-> register(zeemq_server,spawn(?MODULE,server,[])),ok.因此,假设节点B上的进程
server()-> receive {{CallerPid, Ref}, {Module, Func, Args}} -> Result = (catch erlang:apply(Module, Func, Args)), CallerPid ! {Ref, Result}, server(); _ -> server() end.
zeemq_server
永远不会关闭,并且节点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上运行的进程的瞬时数量,这可能会因内存而极大地影响服务。但是,它看起来很好,并使
server()
循环立即返回以处理下一个请求。你对这个修改有什么看法? Pool of receiver Threads
,但在节点A方面似乎只有一个Name
。这样,传入的消息在接收者之间被多路复用线程和这组进程中共享的负载。保持问题的含义相同。Erlangers
!
答案 0 :(得分:2)
除了内存量之外,进程邮箱中的最大邮件数是无限制的。
此外,如果您需要检查邮箱大小,请使用
erlang:process_info(self(),[message_queue_len,messages]).
这将返回如下内容:
[{message_queue_len,0},{messages,[]}]
我建议您先将服务器转换为gen_server。这是你的工人。
接下来,我建议使用poolboy(https://github.com/devinus/poolboy)来创建服务器实例池作为poolboy worker(在他们的github Readme.md中有一些示例)。最后,我建议使用辅助方法为调用者创建一个模块,该方法创建一个poolboy事务并将一个Worker arg从池应用到一个函数。以下示例来自他们的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。在http://learnyousomeerlang.com/distribunomicon#rpc找到了对Erlang RPC的良好处理。
答案 1 :(得分:0)
IMO产生一个处理每个请求的新流程可能过度,但很难说不知道每个请求需要做什么。
您可以拥有一个进程池来处理每个消息,使用循环方法分发请求或根据请求类型处理它,将其发送到子进程或生成进程。您还可以通过查看其msg队列并在重载时启动新子项来监视池化进程的负载。使用主管..只需在init中使用send_after每隔几秒钟监控负载并采取相应措施。如果可以的话,使用OTP,有开销,但值得。
我不会将http用于专线通信,我相信它的开销太大了。您可以使用一组进程来控制负载来处理它。