2019独角兽企业重金招聘Python工程师标准>>>

什么是 epmd ?

在《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!》中有如下描述:

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.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

实验分析

节点注册

注册信息查询

杀掉 epmd

整个实验抓包

实验操作步骤

初始状态,没有启动 epmd 和任何 erlang 程序

[root@Betty ~]#
[root@Betty ~]# ps aux|grep epmd
root      6843  0.0  0.0 103252   852 pts/2    S+   14:45   0:00 grep epmd
[root@Betty ~]#
[root@Betty ~]# ps aux|grep beam
root      6845  0.0  0.0 103252   848 pts/2    S+   14:45   0:00 grep beam
[root@Betty ~]#

在另一个窗口启动分布式 erlang 节点 a

[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相关推荐

  1. Erlang模块erl翻译

    命令: erl 概述: Erlang模拟器 描述: erl程序启动一个Erlang运行时系统.准确的信息是依赖于系统的(举例,erl是否是脚本或程序,其它程序调用). 相反,windows用户可能想要 ...

  2. 【原创】erlang 模块之 application

    2019独角兽企业重金招聘Python工程师标准>>> kernel-2.15.2 中的内容 1 2 3 4 5 6 7 8 9 10 11 12 13 14 转载于:https:/ ...

  3. Erlang模块gen_tcp翻译

    概述 TCP/IP套接字接口 描述 gen_tcp模块提供了使用TCP / IP协议与套接字进行通信的功能. 以下代码片段提供了一个客户端连接到端口5678的服务器的简单示例,传输一个二进制文件并关闭 ...

  4. elixir添加erlang模块

    elixir 添加依赖一般都是在hex仓库中 在mix.exs的deps函数中写入 defp deps do[{:my_dep, "~> 0.3.0"}]end#执行mix ...

  5. erlang精要(7)-模块

    1.模块是具有名字的文件,其中包含一组函数. 2.Erlang中所有函数必须定义在模块中. 3.erlang模块会被自动引入,其它模块需要 调用 module:function(arguments) ...

  6. 【原创】Erlang 之 entop 使用问题

    2019独角兽企业重金招聘Python工程师标准>>> 工欲善其事,必先利其器.排查 erlang 系统问题时,肯定希望能有一个像 Unix top 一样的工具,entop 就是这么 ...

  7. erlang rpc 远程调用

    跨节点进行远程调用的时候,会经常用到rpc模块提供的方法,例如rpc:call.rpc:cast.那么每个节点上的rpc模块是怎么工作的呢? rex进程 rpc模块的启动过程很简单,并没有初始化做太多 ...

  8. Erlang 数据类型。。

    2019独角兽企业重金招聘Python工程师标准>>> 数值 二进制串/位串 原子 元祖 列表 唯一标识符(pid,端口,引用) Fun 函数 Erlang 中的数据通常被称作项式 ...

  9. Windows下Erlang开发环境搭建

    1.下载otp_win32_R15B.exe,并安装: 2.配置环境变量 a.增加用户变量ERL_HOME,变量值为C:\Program Files\erl5.9(erlang的安装路径). b.编辑 ...

最新文章

  1. es根据字段长度过滤_Es 根据数组长度查询
  2. oracle表设置主键自增长,笔记:oracle表设置主键自增长
  3. SwiftUI之如何使用@EnvironmentObject在视图之间共享数据
  4. python4 什么时候_Python4要来了?快来看看Python之父怎么说
  5. (字符串)字符串中首先出现两次的字符
  6. Linux下的JAVA命令参数_以java命令为例解析linux命令行调用语句
  7. 国货如此畸形,改革30年无国际品牌
  8. 孙燕姿:(Hello, I'm Stefanie...)
  9. 【渗透测试】Sunlogin-RCE(向日葵)
  10. 手机用计算机解锁,如何用电脑解锁手机屏幕
  11. springboot 删除路径下面所有文件_[原创]springboot 中 resources 资源目录里面的文件夹压缩下载...
  12. linux fdisk等命令,linux命令:fdisk(示例代码)
  13. 华为OD机考 2022
  14. 最强Verilog例化说明
  15. UE4 Random Unit Vector In Cone
  16. 直播app代码公布:视频直播源码转盘功能的实现
  17. java基础面试题及答案
  18. 在线教育,异军突起,有一种华丽转身,叫做.NET在线讲师!(全职/兼职皆可)...
  19. 2012年9月TIOBE编程语言排行榜:Objective-C继续推进
  20. 友勤签约中信重工Oracle P6项目管理软件及技术服务项目

热门文章

  1. java split函数报错
  2. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-Switch Case语句是否会自动跳转到下一个
  3. nodejs+vue.js+webpack
  4. 流程流转相关业务与流转的分离
  5. 设计模式 - Composite
  6. 关于多库操作一些想法
  7. Windows句柄-2
  8. 函数中的指针分配的内存怎么释放
  9. python自动生成word版本试卷_Python解决问题:生成包含加减练习题的Word文件
  10. 渗透测试报告封面样本