1. 程式人生 > >Erlang epmd的角色以及使用

Erlang epmd的角色以及使用

很多同學誤會了epmd的作用,認為epmd就是erlang叢集的協議,我來澄清下:

Epmd是Erlang Port Mapper Daemon的縮寫,在Erlang叢集中的作用相當於dns的作用,提供節點名稱到埠的查詢服務,epmd繫結在總所周知的4369埠上。

epmd文件:這裡
epmd協議:這裡

Erlang的節點名稱是類似這樣的[email protected]的格式,當一個節點啟動的時候,首先會在本機啟動epmd,同時把自己的節點名稱和節點監聽的tcp埠登記在上面。
看程式碼:

// erlexec.c

...

case 'n':

                    if (strcmp(argv[i], "-name") == 0) { /* -name NAME */

                        if (i+1 >= argc)

                            usage("-name");

 

                        /*                                                                                                                                             

                         * Note: Cannot use add_args() here, due to non-defined                                                                                        

                         * evaluation order.                                                                                                                           

                         */

 

                        add_arg(argv[i]);

                        add_arg(argv[i+1]);

                        isdistributed = 1;

                        i++;

...

case 's':     /* -sname NAME */

                    if (strcmp(argv[i], "-sname") == 0) {

                        if (i+1 >= argc)

                            usage("-sname");

                        add_arg(argv[i]);

                        add_arg(argv[i+1]);

                        isdistributed = 1;

                        i++;

                    }

...

    if (isdistributed && !no_epmd)

        start_epmd(epmd_prog);

...

我們可以透過erl -epmd EPMD_PROG來傳入不同的引數。

再看下實驗:

$erl -sname a

$erl -sname b

$erl -sname c

$ ps -ef|grep epmd

membase   4592     1  0 Aug25 ?        00:00:39 /usr/local/bin/epmd -daemon

...

$ netstat -an|grep 4369

tcp        0      0 0.0.0.0:4369                0.0.0.0:*                   LISTEN   

$ epmd -names

epmd: up and running on port 4369 with data:

name c at port 4096

name b at port 4097

name a at port 4098

...

$erl -sname x

Erlang R14B04 (erts-5.8.5) 1 [64-bit] [smp:16:16] [rq:16] [async-threads:0] [hipe] [kernel-poll:false]

 

Eshell V5.8.5  (abort with ^G)

(
[email protected]
)1> erl_epmd:port_please(x, "127.0.0.1"). {port,34625,5}   ([email protected])2> erl_epmd:names(). {ok,[{"a",4096},{"b",4097},{"c",4098},{"x",34625}]}

epmd是個標準的tcp伺服器,它的協議如下:

kernel的erl_epmd模組提供epmd協議的封裝,向net_kernel模組提供服務。如果net_kernel要連線其他節點的時候,就取出節點名稱的ip部分,透過erl_epmd建立連線到ip:4369,通過epmd協議來查詢想要的foo的埠,然後再用ip:port去連線真正的服務。

新版本的epmd提供了強行移除名稱的功能,避免由於erlang虛擬機器由於某種原因crash,沒有登出名字,導致無法再使用這個名字。
要使用stop功能,epmd必須以 -relaxed_command_check 啟動,具體參考epmd –help
演示下:

$ erl -sname x -epmd "epmd -relaxed_command_check -daemon"

Erlang R14B04 (erts-5.8.5) 1 [64-bit] [smp:16:16] [rq:16] [async-threads:0] [hipe] [kernel-poll:false]

 

Eshell V5.8.5  (abort with ^G)

([email protected])1>

 

$ epmd -names

epmd: up and running on port 4369 with data:

name x at port 58953

$ epmd -stop x

STOPPED

$ epmd -names

epmd: up and running on port 4369 with data:

我們看到名稱已經搶先移除成功。

祝玩得開心!