RPC(Remote Procedure Call)远程程序调用:编程
若是要给另外一个节点发信息:能够简单写成:服务器
call(Msg,Node) -> {server,Node}!{self(),Msg}, receive {ok,Res} -> Res end. server() -> register(server,self()), loop(). loop() -> receive {Pid,N} -> Pid!{ok,N*N} end, loop().
以上就是RPC的原型,可是要注意本地调用和远程调用区别在于远程节点可能失效,能够加个超时:cookie
call(Msg,Node) -> {server,Node}!{self(),Msg}, receive {ok,Res} -> Res after 1000 -> {error,timeout} end.
Tip: 可是要特别注意的是:超时后仍可能收到消息并存储在进程邮箱中,远程服务器很忙或网络不佳时,若是你不刷新消息,下次call/2而且发送一个新的请求时,最终你取出了是队列的每个消息,就是你call(A,Node)timeout了,又call(B,Node),可能你获得的是A的结果,这个不刷新真悲剧。网络
erlang把上面的原理也用gen_server封装了下,就有了rpc:call(Node,Module,Func,Args)这个函数。分布式
以上来源于:Erlang编程指南函数
问题:都已经能够用RPC和远程节点通讯了,还要net_kernel来作什么?oop
注意到,咱们发信息时还要指定对应的Node名字,对于调用者是很差的,(这个参数也很差找),Erlang要的效果是:把本地节点方式和远程节点编写方式统一,将其透明化。spa
由于只要知道PID就能够给它发信息这个特性,能够分2步完成。code
1. 把要用的节点手动链接起来,server
2.使用增强版本的global:whereis_name/1代替erlang:whereis/1.
因此这就是net_kernel的做用:用于手动启动,中止,链接和监控节点的构造。
这样你发信息能够这样子!和本地是同样了啦!!!
erlang:send(global:whereis_name(test),for_test).
Tips:
1. 这里使用:net_kernel:connect/1成功的前提必定是cookie相同;
2. erl 能够用-connect_all_false 标记,来不让别的节点链接,系统也不会保留链接节点的全局表,这样就能够阻止全局声明。
3. erl –hidden将节点隐藏起来:缘由若是N个节点隐藏互连,就会互相监视,要保持N*(N-1)/2的链接,增长了节点凌晨发送监控消息的开销,因此就把不用的节点先隐藏,要用的时候再用net_kerlel:connect(Node)创建;
4. erl –name –sname 最好不要混用;
5. nep_adm: ping(Node)能够Node有没有链接上来pong通,pang不通.
epmd进程:若是你是在用UDP或TCP等协议来作分布式的话:
如下摘自Erlang编程指南:
epmd是erlang运行时系统的一部分,它为erlang分布式的节点扮演了端口映射看守程序的角色,不管多少分布式节点运行在它上面,每一个机器 只会启动一个epmd看守程序进程,监听来本身端口4369的全部链接请求,并把综们映射到被接节点的监听端口,若是尚未开始运行,当启动你第一个分布式erlang节点时epmd会自动运行,而后经过 手动开启,能够传递一系列的命令和设置参数。