【原创】erlang 模块之 epmd
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                【原创】erlang 模块之 epmd
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
                                2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
什么是 epmd ?
在《Erlang/OTP 并發(fā)編程實(shí)戰(zhàn)》中,對(duì) epmd 有如下描述:
- epmd ?代表 Erlang 端口映射守護(hù)進(jìn)程(Erlang Port Mapper Daemon)。
- 每啟動(dòng)一個(gè)節(jié)點(diǎn),都會(huì)檢查本地機(jī)器上是否運(yùn)行著 epmd ,如果沒(méi)有,節(jié)點(diǎn)就會(huì)自行啟動(dòng) epmd 。
- epmd 會(huì)追蹤在本地機(jī)器上運(yùn)行的每個(gè)節(jié)點(diǎn),并記錄分配給它們的端口。
- 當(dāng)一臺(tái)機(jī)器上的 Erlang 節(jié)點(diǎn)試圖與某遠(yuǎn)程節(jié)點(diǎn)通信時(shí),本地的 epmd 就會(huì)聯(lián)絡(luò)遠(yuǎn)程機(jī)器上的 epmd(默認(rèn)使用 TCP/IP 端口 4369),詢問(wèn)在遠(yuǎn)程機(jī)器上有沒(méi)有叫相應(yīng)名字的節(jié)點(diǎn)。如果有,遠(yuǎn)程的 epmd 就會(huì)回復(fù)一個(gè)端口號(hào),通過(guò)該端口便可直接與遠(yuǎn)程節(jié)點(diǎn)通信。
- epmd 不會(huì)自動(dòng)搜索其他 epmd ,只有在某個(gè)節(jié)點(diǎn)主動(dòng)搜尋其他節(jié)點(diǎn)時(shí)通信才能建立。?
When you start a node, you give it a name, and it will connect to an application called Erlang Port Mapper Daemon (EPMD), which will run on each of the computers that are part of your Erlang cluster. EPMD will act as a name server that lets nodes register themselves, contact other nodes by name rather than port numbers, and warn you about any name clashes. If you need to go through a firewall with distributed Erlang (and do not want to tunnel), you will likely want to open a few ports here and there for Erlang communication. In this case, you should open port 4369, the default port for EPMD. It’s a good idea to use this port, because it has been officially registered for EPMD by Ericsson. This means that any standards-compliant operating system you use will have that port free, ready for EPMD.
Erlang 中和 epmd 相關(guān)的文件
在 otp_src_xxx\erts\epmd\ ?中,實(shí)現(xiàn)了 epmd 服務(wù)程序和 epmd 命令行程序。
【epmd.c】
- 函數(shù) epmd_dbg 是對(duì)函數(shù) epmd 的封裝,便于在 debug 模式下使用 epmd ;
- 給出了如何在 linux 和 windows 上實(shí)現(xiàn) daemon 函數(shù),以及與 syslog 的配合;
定義了 epmd 所采用協(xié)議的消息編碼(C語(yǔ)言側(cè)定義)。
【epmd_int.h】
針對(duì)跨平臺(tái)函數(shù)和變量進(jìn)行定義。
【epmd_cli.c】
實(shí)現(xiàn)了 epmd 命令行功能所需的的 API 調(diào)用。
【epmd_srv.c】
- 基于 select 實(shí)現(xiàn)了 epmd 服務(wù)程序的事件驅(qū)動(dòng)主循環(huán);實(shí)現(xiàn)了針對(duì)上述 epmd 協(xié)議的解析。服務(wù)模型為一問(wèn)一答式。
- 通過(guò)對(duì) select 超時(shí)時(shí)間的約束(最大 5s),模擬了 busy server 的 delay_accept 和 delay_write 功能。
在 otp_src_xxx\lib\kernel\src\ 中,在 erlang 代碼層面實(shí)現(xiàn)了與 epmd 服務(wù)程序的協(xié)議交互。
【erl_epmd.erl】
基于 gen_server 行為模式、采用 TCP socket 方式與本地或遠(yuǎn)端 epmd 進(jìn)行協(xié)議通信的實(shí)現(xiàn)。
【erl_epmd.hrl】
定義了 epmd 所使用協(xié)議的消息編碼(Erlang 語(yǔ)言側(cè)定義)。
在 otp_src_xxx\lib\erl_interface\src\epmd\ 中,與 erlang 層實(shí)現(xiàn)對(duì)應(yīng)的底層 C 實(shí)現(xiàn)。
【ei_epmd.h】
常量定義。
【epmd_port.c】
通過(guò) TCP socket 連接本地或遠(yuǎn)端 epmd ,并通過(guò)協(xié)議 EPMD_PORT2_REQ 獲取 the distribution port of another node 。
【epmd_publish.c】
通過(guò)協(xié)議 EPMD_ALIVE2_REQ 向隱藏 node 發(fā)布自身的 listen port 和 alive name。
【epmd_unpublish.c】
通過(guò)協(xié)議 EPMD_STOP_REQ 停止指定名字的 node。
EPMD Protocol
erts-5.9.2 中的內(nèi)容
1
2
3
4
5
6
7
8
9
erts-7.1 中的內(nèi)容
10
11
12
13
14
15
16
17
實(shí)驗(yàn)分析
節(jié)點(diǎn)注冊(cè)
注冊(cè)信息查詢
 
殺掉 epmd
整個(gè)實(shí)驗(yàn)抓包
實(shí)驗(yàn)操作步驟
 初始狀態(tài),沒(méi)有啟動(dòng) epmd 和任何 erlang 程序
[root@Betty ~]# [root@Betty ~]# erl -sname a Erlang/OTP 17 [erts-6.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]Eshell V6.0 (abort with ^G) (a@Betty)1> 重新查看,發(fā)現(xiàn)此時(shí) epmd 已經(jīng)隨之啟動(dòng)
[root@Betty ~]# [root@Betty ~]# ps aux|grep epmd root 6855 0.0 0.0 10828 392 ? S 14:45 0:00 /usr/local/lib/erlang/erts-6.0/bin/epmd -daemon root 6878 0.0 0.0 103252 848 pts/2 S+ 14:45 0:00 grep epmd [root@Betty ~]# [root@Betty ~]# ps aux|grep beam root 6849 0.6 0.4 744584 16652 pts/4 Sl+ 14:45 0:00 /usr/local/lib/erlang/erts-6.0/bin/beam.smp -- -root /usr/local/lib/erlang -progname erl -- -home /root -- -sname a root 6880 0.0 0.0 103252 848 pts/2 S+ 14:46 0:00 grep beam [root@Betty ~]# 查看節(jié)點(diǎn)注冊(cè)信息
[root@Betty ~]# [root@Betty ~]# epmd -names epmd: up and running on port 4369 with data: name a at port 34919 [root@Betty ~]# 在 erlang shell 中查看本地注冊(cè)信息
(a@Betty)1> (a@Betty)1> erl_epmd:names(). {ok,[{"a",34919}]} (a@Betty)2> 查看另一臺(tái)主機(jī) YOYO 上 epmd 的注冊(cè)信息,此時(shí)會(huì)報(bào)錯(cuò)(因?yàn)?YOYO 主機(jī)上此時(shí) epmd 尚未運(yùn)行)
(a@Betty)2> erl_epmd:names("YOYO"). {error,address} (a@Betty)3> 主機(jī) YOYO 尚未運(yùn)行 epmd 時(shí)的狀態(tài)
[root@YOYO ~]# [root@YOYO ~]# ps aux|grep epmd root 7620 0.0 0.0 103256 848 pts/2 S+ 14:47 0:00 grep epmd [root@YOYO ~]# [root@YOYO ~]# ps aux|grep beam root 7622 0.0 0.0 103256 848 pts/2 S+ 14:47 0:00 grep beam [root@YOYO ~]# 啟動(dòng)分布式 erlang 節(jié)點(diǎn) b
[root@YOYO ~]# [root@YOYO ~]# erl -sname b Erlang/OTP 17 [erts-6.0] [source] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]Eshell V6.0 (abort with ^G) (b@YOYO)1> 此時(shí)狀態(tài)變?yōu)?/span>
[root@YOYO ~]# [root@YOYO ~]# ps aux|grep epmd root 7629 0.0 0.0 10828 392 ? S 14:47 0:00 /usr/local/lib/erlang/erts-6.0/bin/epmd -daemon root 7650 0.0 0.0 103256 848 pts/2 S+ 14:47 0:00 grep epmd [root@YOYO ~]# [root@YOYO ~]# ps aux|grep beam root 7623 3.0 0.4 589900 16720 pts/1 Sl+ 14:47 0:00 /usr/local/lib/erlang/erts-6.0/bin/beam.smp -- -root /usr/local/lib/erlang -progname erl -- -home /root -- -sname b root 7652 0.0 0.0 103256 844 pts/2 S+ 14:47 0:00 grep beam [root@YOYO ~]# [root@YOYO ~]# epmd -names epmd: up and running on port 4369 with data: name b at port 40969 [root@YOYO ~]# 在主機(jī) Betty 的 erlang shell 中重新查詢主機(jī) YOYO 上 epmd 的注冊(cè)信息,此時(shí)可以獲得 b 的注冊(cè)內(nèi)容
(a@Betty)3> (a@Betty)3> erl_epmd:names("YOYO"). {ok,[{"b",40969}]} (a@Betty)4> 在主機(jī) YOYO 上的 erlang shell 里反向查詢 Betty 主機(jī)上 epmd 的注冊(cè)信息
(b@YOYO)1> (b@YOYO)1> erl_epmd:names(). {ok,[{"b",40969}]} (b@YOYO)2> erl_epmd:names("Betty"). {ok,[{"a",34919}]} (b@YOYO)3> 終止主機(jī) Betty 上 erlang 節(jié)點(diǎn) a 的運(yùn)行
(a@Betty)4> (a@Betty)4> BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded(v)ersion (k)ill (D)b-tables (d)istribution ^C[root@Betty ~]# [root@Betty ~]# 查看此時(shí)狀態(tài)
[root@Betty ~]# [root@Betty ~]# ps aux|grep beam root 6890 0.0 0.0 103252 852 pts/2 S+ 14:49 0:00 grep beam [root@Betty ~]# [root@Betty ~]# ps aux|grep epmd root 6855 0.0 0.0 10828 424 ? S 14:45 0:00 /usr/local/lib/erlang/erts-6.0/bin/epmd -daemon root 6893 0.0 0.0 103252 852 pts/2 S+ 14:49 0:00 grep epmd [root@Betty ~]# [root@Betty ~]# epmd -names epmd: up and running on port 4369 with data: [root@Betty ~]# 殺死 epmd
[root@Betty ~]# epmd -kill Killed [root@Betty ~]# [root@Betty ~]# [root@Betty ~]# ps aux|grep epmd root 6897 0.0 0.0 103252 852 pts/2 S+ 14:49 0:00 grep epmd [root@Betty ~]#
 
 
轉(zhuǎn)載于:https://my.oschina.net/moooofly/blog/533594
總結(jié)
以上是生活随笔為你收集整理的【原创】erlang 模块之 epmd的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: Win11 Moment 3 新图片曝光
- 下一篇: 对话余承东:华为没必要下场造车 问界不做
