【原创】erlang 模块之 epmd
生活随笔
收集整理的這篇文章主要介紹了
【原创】erlang 模块之 epmd
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2019獨角獸企業重金招聘Python工程師標準>>>
什么是 epmd ?
在《Erlang/OTP 并發編程實戰》中,對 epmd 有如下描述:
- epmd ?代表 Erlang 端口映射守護進程(Erlang Port Mapper Daemon)。
- 每啟動一個節點,都會檢查本地機器上是否運行著 epmd ,如果沒有,節點就會自行啟動 epmd 。
- epmd 會追蹤在本地機器上運行的每個節點,并記錄分配給它們的端口。
- 當一臺機器上的 Erlang 節點試圖與某遠程節點通信時,本地的 epmd 就會聯絡遠程機器上的 epmd(默認使用 TCP/IP 端口 4369),詢問在遠程機器上有沒有叫相應名字的節點。如果有,遠程的 epmd 就會回復一個端口號,通過該端口便可直接與遠程節點通信。
- epmd 不會自動搜索其他 epmd ,只有在某個節點主動搜尋其他節點時通信才能建立。?
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 相關的文件
在 otp_src_xxx\erts\epmd\ ?中,實現了 epmd 服務程序和 epmd 命令行程序。
【epmd.c】
- 函數 epmd_dbg 是對函數 epmd 的封裝,便于在 debug 模式下使用 epmd ;
- 給出了如何在 linux 和 windows 上實現 daemon 函數,以及與 syslog 的配合;
定義了 epmd 所采用協議的消息編碼(C語言側定義)。
【epmd_int.h】
針對跨平臺函數和變量進行定義。
【epmd_cli.c】
實現了 epmd 命令行功能所需的的 API 調用。
【epmd_srv.c】
- 基于 select 實現了 epmd 服務程序的事件驅動主循環;實現了針對上述 epmd 協議的解析。服務模型為一問一答式。
- 通過對 select 超時時間的約束(最大 5s),模擬了 busy server 的 delay_accept 和 delay_write 功能。
在 otp_src_xxx\lib\kernel\src\ 中,在 erlang 代碼層面實現了與 epmd 服務程序的協議交互。
【erl_epmd.erl】
基于 gen_server 行為模式、采用 TCP socket 方式與本地或遠端 epmd 進行協議通信的實現。
【erl_epmd.hrl】
定義了 epmd 所使用協議的消息編碼(Erlang 語言側定義)。
在 otp_src_xxx\lib\erl_interface\src\epmd\ 中,與 erlang 層實現對應的底層 C 實現。
【ei_epmd.h】
常量定義。
【epmd_port.c】
通過 TCP socket 連接本地或遠端 epmd ,并通過協議 EPMD_PORT2_REQ 獲取 the distribution port of another node 。
【epmd_publish.c】
通過協議 EPMD_ALIVE2_REQ 向隱藏 node 發布自身的 listen port 和 alive name。
【epmd_unpublish.c】
通過協議 EPMD_STOP_REQ 停止指定名字的 node。
EPMD Protocol
erts-5.9.2 中的內容
1
2
3
4
5
6
7
8
9
erts-7.1 中的內容
10
11
12
13
14
15
16
17
實驗分析
節點注冊
注冊信息查詢
殺掉 epmd
整個實驗抓包
實驗操作步驟
初始狀態,沒有啟動 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> 重新查看,發現此時 epmd 已經隨之啟動
[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 ~]# 查看節點注冊信息
[root@Betty ~]# [root@Betty ~]# epmd -names epmd: up and running on port 4369 with data: name a at port 34919 [root@Betty ~]# 在 erlang shell 中查看本地注冊信息
(a@Betty)1> (a@Betty)1> erl_epmd:names(). {ok,[{"a",34919}]} (a@Betty)2> 查看另一臺主機 YOYO 上 epmd 的注冊信息,此時會報錯(因為 YOYO 主機上此時 epmd 尚未運行)
(a@Betty)2> erl_epmd:names("YOYO"). {error,address} (a@Betty)3> 主機 YOYO 尚未運行 epmd 時的狀態
[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 ~]# 啟動分布式 erlang 節點 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> 此時狀態變為
[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 ~]# 在主機 Betty 的 erlang shell 中重新查詢主機 YOYO 上 epmd 的注冊信息,此時可以獲得 b 的注冊內容
(a@Betty)3> (a@Betty)3> erl_epmd:names("YOYO"). {ok,[{"b",40969}]} (a@Betty)4> 在主機 YOYO 上的 erlang shell 里反向查詢 Betty 主機上 epmd 的注冊信息
(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> 終止主機 Betty 上 erlang 節點 a 的運行
(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 ~]# 查看此時狀態
[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 ~]#
轉載于:https://my.oschina.net/moooofly/blog/533594
總結
以上是生活随笔為你收集整理的【原创】erlang 模块之 epmd的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win11 Moment 3 新图片曝光
- 下一篇: weblit渲染过程