现在我正在构建一个分布式应用程序,我正在研究使用rpc:cast vs rpc:call,因为我不希望调用进程等待返回值,甚至收到一个。
Cast完全适用于此,但我很好奇,什么进程执行rpc:cast和call传递的函数?我是否应该担心过度/低于并发?
通常,当我想要另一个进程执行代码时,我使用一个工作池并使用gen_server:cast / 2向其中一个发送异步转换并让它们处理它。但对于RPC,它没有定义计算的进程。流程是否已预先分配并等待?或者是每个进程在rpc调用它然后终止时生成?从我读过的内容来看,如果你进行多次调用,这是非常低效的,因为这些过程只是在创建和销毁过程中,而这在计算上并不容易。
提前感谢您的帮助!
答案 0 :(得分:1)
<强> TL; DR:强>
在目标节点上生成的用于处理RPC的进程。
<强>讨论强>
如果我们看一下rpc模块的代码,我们会发现它包含了基本的正常节点间消息传递功能:
https://github.com/erlang/otp/blob/master/lib/kernel/src/rpc.erl#L398-L403
-spec cast(Node, Module, Function, Args) -> true when
Node :: node(),
Module :: module(),
Function :: atom(),
Args :: [term()].
cast(Node, Mod, Fun, Args) when Node =:= node() ->
catch spawn(Mod, Fun, Args),
true;
cast(Node, Mod, Fun, Args) ->
gen_server:cast({?NAME,Node}, {cast,Mod,Fun,Args,group_leader()}),
true.
当发生在当前节点上调用强制转换时,会生成一个新进程,并提供要执行的提供的MFA。如果在不同节点上调用大小写,则通过gen_server:cast/2
将消息发送到指示节点的组长,并且目标节点上的组长将生成处理MFA的进程。 / p>
演员表的处理代码在这里:
https://github.com/erlang/otp/blob/master/lib/kernel/src/rpc.erl#L130-L139
-spec handle_cast(term(), state()) -> {'noreply', state()}.
handle_cast({cast, Mod, Fun, Args, Gleader}, S) ->
spawn(fun() ->
set_group_leader(Gleader),
apply(Mod, Fun, Args)
end),
{noreply, S};
handle_cast(_, S) ->
{noreply, S}. % Ignore !
如果您已经知道要在另一个节点上将消息分派到哪个进程,那么将节点网格视为超级节点可能更有意义,绕过rpc模块完全只是进行gen_server调用或直接转换为它。当然,使用哪种方法是品味和建筑问题。
答案 1 :(得分:1)
流程名称为rex
。这是一个注册过程,它产生一个执行apply(M, F, A)
的过程。
https://github.com/erlang/otp/blob/master/lib/kernel/src/rpc.erl#L28
和
https://github.com/erlang/otp/blob/master/lib/kernel/src/rpc.erl#L402
顺便说一句,这意味着所有rpc:call/4
和rpc:cast/4
以及其他参数都经过一个限制可扩展性的过程。 rpc
模块不适用于高吞吐量目的。