Erlang EPMD


 epmd进程和Erlang节点进程如影随形,在Rabbitmq集群,Ejabberd集群,Couchbase集群产品文档中都会有相当多的内容讲epmd,epmd是什么呢?

  epmd 是Erlang Port Mapper Daemon的缩写,全称足够明确表达它的功能了(相比之下,OTP就是一个难以从字面理解的名字);epmd完成Erlang节点和IP,端口的映射关系,比如在我的测试机上,

[[email protected] data2]# epmd -names
epmd: up and running on port 4369 with data:
name ns_1 at port 21101 name babysitter_of_ns_1 at port 21100 name ligaoren at port 51056

新启动一个节点之后,再看下epmd的情况:

[[email protected] data2]# erl -name [email protected] -setcookie 1234 [[email protected] ~]# epmd -names
epmd: up and running on port 4369 with data:
name test at port 35441 name ns_1 at port 21101 name babysitter_of_ns_1 at port 21100 name ligaoren at port 51056

epmd什么时候启动?

文档里面说的是"
 if the node is to be distributed ",其实从实际操作的角度看,只要启动时候启动选项包含-name 或者-sname就会自动启动epmd;如果由于意外关闭了epmd进程,可以通过/usr/local/lib/erlang/erts-6.0/bin/epmd -daemon 启动epmd(注意版本不同路径也会不同).下面我们分别通过erl -sname tt 和 erl 启动两个节点,通过observer看下两种方式启动之后的应用程序结构,比较一下可以发现,前者多启动了net_kernel和erl_epmd进程.


如何让epmd只侦听指定的IP

要实现这个目标,有两种方式,1.使用环境变量

ERL_EPMD_ADDRESS=127.0.0.1 epmd -daemon

或者使用启动参数

epmd -address IPList 

或者

erl ... -kernel inet_dist_use_interface "{127,0,0,1}"

如何指定Erlang节点互联的动态端口范围

从上面的简单实验可以看到每个分布式节点启动之后,都会在epmd一个动态的端口用来节点间通信.在实际的环境中,我们不可能在防火墙里面把所有的端口都开放出来,那么怎么限制Erlang节点使用的端口范围呢?答案就是 inet_dist_listen_min inet_dist_listen_max 选项

erl -sname abc  -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375 erl -sname node1  -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375 erl -sname node2  -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375 erl -sname node3  -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375 erl -sname node4  -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375 erl -sname node5  -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375

在启动上面节点的时候,我们显示指定了kernel的 inet_dist_listen_min inet_dist_listen_max值,也就是节点可侦听端口的最小值,最大值.上面节点启动成功之后,我们通过epmd -names查看一下端口注册情况

epmd: up and running on port 4369 with data:
name node5 at port 4375 name node4 at port 4374 name node3 at port 4373 name node2 at port 4372 name node1 at port 4371 name abc at port 4370

这时,我们尝试再创建一个节点试一下

erl -sname node6  -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375

失败了,错误信息节录如下:

{error_logger,{{2014,7,3},{20,51,4}},"Protocol: ~tp: register/listen error: ~tp~ n",["inet_tcp",eaddrinuse]} {error_logger,{{2014,7,3},{20,51,4}},crash_report,[[{initial_call,{net_kernel,in it,[‘Argument__1‘]}},{pid,<0.20.0>},{registered_name,[]},{error_info,{exit,{erro
r,badarg},[{gen_server,init_it,6,[{file,"gen_server.erl"},{line,320}]},{proc_lib
,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]}},{ancestors,[net_sup,ke
rnel_sup,<0.10.0>]},{messages,[]},{links,[<0.17.0>]},{dictionary,[{longnames,fal
se}]},{trap_exit,true},{status,running},{heap_size,610},{stack_size,27},{reducti
ons,1861}],[]]}

是的,启动失败的原因是在epmd注册失败,没有可用的动态端口可以分配给新节点了,所以报出的是地址正在使用的错误.

注:上面参数修改如果是在代码中完成,如下

application:set_env(kernel, inet_dist_listen_min, 9100).
 application:set_env(kernel, inet_dist_listen_max, 9105).

这个在 Erlang FAQ中有提到 
http://www.erlang.org/faq/how_do_i.html 5.18  ...run distributed Erlang through a firewall?

如果是配置在Confige文件中,配置节为:

{ kernel, [
            {inet_dist_listen_min, 6000},
            {inet_dist_listen_max, 7999}
          ]}

LYSE里面就给出了使用配置文件的路子,只不过他是把这个配置放在专门的配置文件

http://learnyousomeerlang.com/distribunomicon

如果这两个参数调整了,最好干掉epmd,重新启动,之所以这样是因为epmd在所有节点关闭之后还会存在,所以必须重启以便新参数生效.

如何让epmd使用指定端口

默认情况下epmd使用的TCP端口是4369

ERL_EPMD_ADDRESS=127.0.0.1 ERL_EPMD_PORT=8384 epmd -daemon

交互模式下要链接指定的端口可以使用port选项

epmd  -port 8384 -names

调试状态看细节

如果启动epmd -d 启动调试,可以看到输出信息;下面的过程,我逐一启动了abc,xyz,test三个节点;然后关闭掉xyz,test节点,从下面的输出信息,可以看到节点注册和注销注册的情况.

 [[email protected] ~]#
[[email protected] ~]# epmd -d
epmd: Thu Jul 3 15:56:15 2014: epmd running - daemon = 0 epmd: Thu Jul 3 15:56:25 2014: ** got ALIVE2_REQ
epmd: Thu Jul 3 15:56:25 2014: registering ‘abc:2‘, port 35383 epmd: Thu Jul 3 15:56:25 2014: type 77 proto 0 highvsn 5 lowvsn 5 epmd: Thu Jul 3 15:56:25 2014: ** sent ALIVE2_RESP for "abc" epmd: Thu Jul 3 15:56:43 2014: ** got ALIVE2_REQ
epmd: Thu Jul 3 15:56:43 2014: registering ‘xyz:2‘, port 42802 epmd: Thu Jul 3 15:56:43 2014: type 77 proto 0 highvsn 5 lowvsn 5 epmd: Thu Jul 3 15:56:43 2014: ** sent ALIVE2_RESP for "xyz" epmd: Thu Jul 3 15:57:22 2014: ** got ALIVE2_REQ
epmd: Thu Jul 3 15:57:22 2014: node name already occupied abc
epmd: Thu Jul 3 15:57:22 2014: ** sent ALIVE2_RESP for "abc" epmd: Thu Jul 3 15:57:22 2014: trying to unregister node with unknown file descriptor 6 epmd: Thu Jul 3 15:57:51 2014: ** got ALIVE2_REQ
epmd: Thu Jul 3 15:57:51 2014: registering ‘test:1‘, port 32781 epmd: Thu Jul 3 15:57:51 2014: type 77 proto 0 highvsn 5 lowvsn 5 epmd: Thu Jul 3 15:57:51 2014: ** sent ALIVE2_RESP for "test" epmd: Thu Jul 3 15:58:23 2014: ** got PORT2_REQ
epmd: Thu Jul 3 15:58:23 2014: ** sent PORT2_RESP (ok) for "test" epmd: Thu Jul 3 16:05:26 2014: unregistering ‘xyz:2‘, port 42802 epmd: Thu Jul 3 16:05:35 2014: unregistering ‘test:1‘, port 32781

是不是比较迷惑里面的ALIVE2_REQ之类的是什么意思?这就要认真对照Erlang Distribution Protocol了,对照下面的图,如果有兴趣可以研究下协议,地址: 
http://www.erlang.org/doc/apps/erts/erl_dist_protocol.html

最后,这里有一个Golang的项目 Eclus-EPMD replacement in Go 有兴趣的可以看下,项目地址: https://github.com/goerlang/eclus

时间: 2024-11-01 22:38:57

Erlang EPMD的相关文章

Erlang epmd官方文档中文翻译

本文含epmd简介及官方文档之翻译,文档地址 http://erlang.org/doc/man/epmd.html翻译时的版本 R19.1 中英文水平都不咋地,不通顺处海涵,就酱. 简介 Erlang分布式系统中节点是通过节点名字互相连接的,节点名字为[email protected]_ADDRESS格式. epmd是分布式erlang中比较重要的模块.集群中每台机器都有一个epmd进程,这些进程端口号都用同一个端口号(默认4396端口).所有节点启动的时候都会连接到本机对应的epmd进程,它

erlang epmd 自定义端口号

epmd,是erlang集群节点间端口映射的守护进程,负责维护集群内的节点连接,提供节点名称到IP地址及端口的解析服务. epmd 自定义端口号 epmd端口配置 默认情况下,epmd绑定在4369端口.但是,端口固定的话,容易遭受攻击,可能导致新节点的认证失败而无法启动,或无法加入集群. epmd -daemon -port 5000 如果想用调试模式启动 epmd,使用 epmd -d -port 5000 另外,epmd通常伴随着erlang节点启动时自动启动,无须手动处理,所以,这里也可

Erlang与C构建的节点通讯

Erlang节点之间的通讯,主要用于两个Erlang节点之间的通讯,但Erlang还支持与java构建的节点通讯,甚至与c构建的节点通讯,前面两种方式在我以前的文章都有讲到,所以这里讲Erlang与c构建的节点通讯. Cnode与erl_interface 想用C构建一个erlang节点,要利用Erlang的erl_interface接口来实现.c建立的节点,叫CNode ,其中,erl_interface除了实现一些基本的节点连接,消息发送接收,还实现Erlang Term 的构建解析. CN

Ejabberd源码解析前奏--安全

一.防火墙设置    当你配置防火墙的时候,你需要注意以下 TCP 端口: 端口 描述 5222 用于 Jabber/XMPP 客户端连接的标准端口, 纯文本或 STARTTLS. 5223 Jabber 客户端使用旧的 SSL 方法连接的标准端口 . 5269 用于 Jabber/XMPP 服务器连接的标准端口. 4369 EPMD  监听Erlang节点名请求. 端口范围 用于两个Erlang节点之间的连接. 这个范围是可配置的(参见第二部分即epmd). 二.epmdepmd (Erlan

Erlang的erl与epmd的区别与联系

1.epmd是Erlang Port Mapper Daemon的缩写,完成Erlang节点和IP,端口的映射关系,不同节点间的通信要靠epmd进程进行沟通. 2.erl是启动erlang虚拟机的命令. 3.从实际操作的角度看,只要执行erl选项包含-name 或者-sname就会自动启动epmd和net_kernel.如果由于意外关闭了epmd进程,可以通过/usr/local/lib/erlang/erts-6.0/bin/epmd -daemon 启动epmd(注意版本不同路径也会不同).

对Erlang开发者的几点建议

* 确保没有任何编译警告 * Erlang中String采用list实现,32位系统中,其1个字符用8个字节的空间(4个保存value, 4个保存指针).因此string速度较慢,空间占用较大 * 在Server中,总是尽力书写尾递归(tail-recursive)的函数 * 使用'++'时,left list会被拷贝,然后添加到right list的头部,因此最好把length较短的list放在左侧 * 避免使用regexp,如果需要正则表达式,请使用re * timer模块的大部分函数实现,

erlang在windows下和虚拟机节点通信

在Linux下部署erlang项目,开发过程很多都是在Windows完成的,然后再发布到Linux,所以测试过程要在虚拟机下完成.有一天因为想要在虚拟机中使用到erlang图形化工具,比如appmon.tv.observer等等,便突发奇想得利用Windows的erlang连接到虚拟机中使用这些工具,来查看虚拟机的运行状态. 需要准备哪些东西? 我是在VmWare10虚拟Centos6.5系统,所以这里以VmWare10和Centos6.5为例,其他Linux系统及工具只做参考. 注意了,Lin

erlang分布式入门(一)-ping pong

erlang分布式入门(一)-ping pong 测试环境和http://willvvv.iteye.com/blog/1523918 一样,192.168.0.182(centos-182)和192.168.0.183(centos-183), 1.按照上面链接(步骤1-4)设置通过ssh hostname 免输入密码直接登录. 2.设置erlang的magiccookie,由于都是以root账号操作,分别在两台机子上执行以下命令 cd /root vi .erlang.cookie 输入 S

Erlang 转至维基百科

Erlang(英语发音:/??rlæ?/)是一种通用的并行程序设计语言,它由乔·阿姆斯特朗(Joe Armstrong)在瑞典电信设备制造商爱立信所辖的计算机科学研究室开发,目的是创造一种可以应付大规模开发活动的程序设计语言和运行环境.Erlang于1987年发布正式版本,最早是爱立信拥有的私有软件,经过十年的发展,于1998年发表开放源代码版本. Erlang是运作于虚拟机的解释型语言,但是现在也包含有乌普萨拉大学高性能Erlang计划(HiPE)[2]开发的原生代码编译器,自R11B-4版本