跨节点进行远程调用的时候,会经常用到rpc模块提供的方法,例如rpc:call、rpc:cast。那么每个节点上的rpc模块是怎么工作的呢?
rex进程
rpc模块的启动过程很简单,并没有初始化做太多事情,以{local,rex}的名称启动了一个gen_server进程,这个gen_server进程的state是一个gb_trees的数据结构。
-spec start() -> {'ok', pid()} | 'ignore' | {'error', term()}.
start() ->
gen_server:start({local,?NAME}, ?MODULE, [], []).
-spec start_link() -> {'ok', pid()} | 'ignore' | {'error', term()}.
start_link() ->
gen_server:start_link({local,?NAME}, ?MODULE, [], []).
业务进程调用rpc:call
rpc模块中比较常用的就是rpc:call和rpc:cast
call/4 和 call/5 这个两个接口的区别,只是在timeout时间是自定义还是infinity而已。
call(Node,M,F,A,Timeout) 内部根据Node是否为本地节点,又分为local_call/3和do_call/3。
这里我们可以通过rpc.erl来查看。
同个节点local_call
local_call根据MFA直接调用apply执行。
local_call(M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
case catch apply(M, F, A) of
{'EXIT',_}=V -> {badrpc, V};
Other -> Other
end.
远程节点do_call
do_call(Node, {call, M,F,A,group_leader()},Timeout)
do_call(Node,