在《Erlang/OTP 并发编程实战》中,对 epmd 有如下描述:
- epmd 代表 Erlang 端口映射守护进程(Erlang Port Mapper Daemon)。
- 每启动一个节点,都会检查本地机器上是否运行着 epmd ,如果没有,节点就会自行启动 epmd 。
- epmd 会追踪在本地机器上运行的每个节点,并记录分配给它们的端口。
- 当一台机器上的 Erlang 节点试图与某远程节点通信时,本地的 epmd 就会联络远程机器上的 epmd(默认使用 TCP/IP 端口 4369),询问在远程机器上有没有叫相应名字的节点。如果有,远程的 epmd 就会回复一个端口号,通过该端口便可直接与远程节点通信。
- epmd 不会自动搜索其他 epmd ,只有在某个节点主动搜寻其他节点时通信才能建立。
在《Learn You Some Erlang for Great Good!》中有如下描述:
Erlang 中和 epmd 相关的文件
在 otp_src_xxx\erts\epmd\ 中,实现了 epmd 服务程序和 epmd 命令行程序。
【epmd.c】
- 函数 epmd_dbg 是对函数 epmd 的封装,便于在 debug 模式下使用 epmd ;
- 给出了如何在 linux 和 windows 上实现 daemon 函数,以及与 syslog 的配合;
【epmd.h】
定义了 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