[Erlang04]爲何有了rpc還有net_kernel:connect/1?

問題描述:

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會自動運行,而後經過 手動開啓,能夠傳遞一系列的命令和設置參數。

相關文章
相關標籤/搜索