epmd进程和Erlang节点进程如影随形,在Rabbitmq集群,Ejabberd集群,Couchbase集群产品文档中都会有相当多的内容讲epmd,epmd是什么呢?
  epmd 是Erlang Port Mapper Daemon的缩写,全称足够明确表达它的功能了(相比之下,OTP就是一个难以从字面理解的名字);epmd完成Erlang节点和IP,端口的映射关系,比如在我的测试机上,
 
[root@nimbus data2]# epmd -names
epmd: up and running on port with data:
name ns_1 at port
name babysitter_of_ns_1 at port
name ligaoren at port
新启动一个节点之后,再看下epmd的情况:
 
[root@nimbus data2]# erl -name test@nimbus -setcookie
[root@nimbus ~]# epmd -names
epmd: up and running on port with data:
name test at port
name ns_1 at port
name babysitter_of_ns_1 at port
name ligaoren at port
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  inet_dist_listen_max
erl -sname node1 -kernel inet_dist_listen_min inet_dist_listen_max
erl -sname node2 -kernel inet_dist_listen_min inet_dist_listen_max
erl -sname node3 -kernel inet_dist_listen_min inet_dist_listen_max
erl -sname node4 -kernel inet_dist_listen_min inet_dist_listen_max
erl -sname node5 -kernel inet_dist_listen_min inet_dist_listen_max
在启动上面节点的时候,我们显示指定了kernel的 inet_dist_listen_min inet_dist_listen_max值,也就是节点可侦听端口的最小值,最大值.上面节点启动成功之后,我们通过epmd -names查看一下端口注册情况
 
epmd: up and running on port  with data:
name node5 at port
name node4 at port
name node3 at port
name node2 at port
name node1 at port
name abc at port
这时,我们尝试再创建一个节点试一下
erl -sname node6  -kernel inet_dist_listen_min  inet_dist_listen_max 
失败了,错误信息节录如下:
 
{error_logger,{{,,},{,,}},"Protocol: ~tp: register/listen error: ~tp~
n",["inet_tcp",eaddrinuse]}
{error_logger,{{,,},{,,}},crash_report,[[{initial_call,{net_kernel,in
it,['Argument__1']}},{pid,<0.20.>},{registered_name,[]},{error_info,{exit,{erro
r,badarg},[{gen_server,init_it,,[{file,"gen_server.erl"},{line,}]},{proc_lib
,init_p_do_apply,,[{file,"proc_lib.erl"},{line,}]}]}},{ancestors,[net_sup,ke
rnel_sup,<0.10.>]},{messages,[]},{links,[<0.17.>]},{dictionary,[{longnames,fal
se}]},{trap_exit,true},{status,running},{heap_size,},{stack_size,},{reducti
ons,}],[]]}
 
是的,启动失败的原因是在epmd注册失败,没有可用的动态端口可以分配给新节点了,所以报出的是地址正在使用的错误.
 
注:上面参数修改如果是在代码中完成,如下
 application:set_env(kernel, inet_dist_listen_min, ).
application:set_env(kernel, inet_dist_listen_max, ).
  这个在 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, },
{inet_dist_listen_max, }
]}
 
LYSE里面就给出了使用配置文件的路子,只不过他是把这个配置放在专门的配置文件
如果这两个参数调整了,最好干掉epmd,重新启动,之所以这样是因为epmd在所有节点关闭之后还会存在,所以必须重启以便新参数生效.
 
如何让epmd使用指定端口
默认情况下epmd使用的TCP端口是4369
ERL_EPMD_ADDRESS=127.0.0.1 ERL_EPMD_PORT= epmd -daemon 
交互模式下要链接指定的端口可以使用port选项
 epmd  -port  -names

调试状态看细节

如果启动epmd -d 启动调试,可以看到输出信息;下面的过程,我逐一启动了abc,xyz,test三个节点;然后关闭掉xyz,test节点,从下面的输出信息,可以看到节点注册和注销注册的情况.
 
[root@Slave4 ~]#
[root@Slave4 ~]# epmd -d
epmd: Thu Jul :: : epmd running - daemon =
epmd: Thu Jul :: : ** got ALIVE2_REQ
epmd: Thu Jul :: : registering 'abc:2', port
epmd: Thu Jul :: : type proto highvsn lowvsn
epmd: Thu Jul :: : ** sent ALIVE2_RESP for "abc"
epmd: Thu Jul :: : ** got ALIVE2_REQ
epmd: Thu Jul :: : registering 'xyz:2', port
epmd: Thu Jul :: : type proto highvsn lowvsn
epmd: Thu Jul :: : ** sent ALIVE2_RESP for "xyz"
epmd: Thu Jul :: : ** got ALIVE2_REQ
epmd: Thu Jul :: : node name already occupied abc
epmd: Thu Jul :: : ** sent ALIVE2_RESP for "abc"
epmd: Thu Jul :: : trying to unregister node with unknown file descriptor
epmd: Thu Jul :: : ** got ALIVE2_REQ
epmd: Thu Jul :: : registering 'test:1', port
epmd: Thu Jul :: : type proto highvsn lowvsn
epmd: Thu Jul :: : ** sent ALIVE2_RESP for "test"
epmd: Thu Jul :: : ** got PORT2_REQ
epmd: Thu Jul :: : ** sent PORT2_RESP (ok) for "test"
epmd: Thu Jul :: : unregistering 'xyz:2', port
epmd: Thu Jul :: : unregistering 'test:1', port
 是不是比较迷惑里面的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  
 
参考资料:
 
 

[Erlang 0123] Erlang EPMD的更多相关文章

  1. Erlang 103 Erlang分布式编程

    Outline 笔记系列 Erlang环境和顺序编程Erlang并发编程Erlang分布式编程YawsErlang/OTP 日期              变更说明 2014-11-23 A Outl ...

  2. [Erlang 0129] Erlang 杂记 VI

    把之前阅读资料的时候记下的东西,整理了一下. Adding special-purpose processor support to the Erlang VM   P23 简单介绍了Erlang C ...

  3. [Erlang 0124] Erlang Unicode 两三事 - 补遗

    最近看了Erlang User Conference 2013上patrik分享的BRING UNICODE TO ERLANG!视频,这个分享很好的梳理了Erlang Unicode相关的问题,基本 ...

  4. [Erlang 0122] Erlang Resources 2014年1月~6月资讯合集

    虽然忙,有些事还是要抽时间做; Erlang Resources 小站 2014年1月~6月资讯合集,方便检索.      小站地址: http://site.douban.com/204209/   ...

  5. [Erlang 0105] Erlang Resources 小站 2013年1月~6月资讯合集

    很多事情要做,一件一件来; Erlang Resources 小站 2013年1月~6月资讯合集,方便检索.      小站地址: http://site.douban.com/204209/     ...

  6. [Erlang 0057] Erlang 排错利器: Erlang Crash Dump Viewer

    http://www.cnblogs.com/me-sa/archive/2012/04/28/2475556.html Erlang Crash Dump Viewer真的是排错的天兵神器,还记得我 ...

  7. [Erlang 0119] Erlang OTP 源码阅读指引

      上周Erlang讨论群里面提到lists的++实现,争论大多基于猜测,其实打开代码看一下就都明了.贴出代码截图后有同学问这代码是哪里找的?   "代码去哪里找?",关于Erla ...

  8. [Erlang 0118] Erlang 杂记 V

       我在知乎回答问题不多,这个问题: "对你职业生涯帮助最大的习惯是什么?它是如何帮助你的?",我还是主动回答了一下.    做笔记 一开始笔记软件做的不好的时候就发邮件给自己, ...

  9. [Erlang 0114] Erlang Resources 小站 2013年7月~12月资讯合集

    Erlang Resources 小站 2013年7月~12月资讯合集,方便检索.     附 2013上半年盘点: Erlang Resources 小站 2013年1月~6月资讯合集    小站地 ...

随机推荐

  1. JS的Object漫想:从现象到“本质”

    转自:http://zzy603.iteye.com/blog/973649 写的挺好,用于记录,把对象分成概念的Object(var f={})和 类的Object(function F(){}) ...

  2. BootStrap_04之jQuery插件(导航、轮播)、以及Less

    1.列偏移与列排序: ①列偏移:控制列出现的位置,某列偏移后,后序列会随之偏移--只能右偏移: col-lg/md/sm/xs-offset-*; ②列排序:控制某一列的位置,该列可以左(pull)右 ...

  3. 【兼容写法】HttpServerUtility.Execute 在等待异步操作完成时被阻止。关键词:MVC,分部视图,异步

    异常处理汇总-后端系列 http://www.cnblogs.com/dunitian/p/4523006.html MVC6之前的版本,对分部视图的异步支持不是很好 问题: 视图里面有分布视图:@{ ...

  4. 【.NET深呼吸】应用上下文(AppContext)

    在.net 4.6中新增了一个类,叫AppContext,这个家伙嘛,技术含量不算高,只不过是在编程的时候可以方便用用而已.应用上下文允许定义一个标识(用字符串表示),并且在应用程序运行期间可以切换状 ...

  5. 【Win10应用开发】签名与验证

    对数据进行签名和验证,是为了防止数据被“盗版”.比较常规的做法是通过公钥进行验证. 算法上多用SAH_xxxx,就是哈希算法.由于MD5后来被发现存在“非唯一性”,你会发现现在很多一些下载的文件验证都 ...

  6. Ajax 提交KindEditor的数据

    这次我是在EasyUI中使用了KindEditor的编辑器,按照官方给的代码,总是无法获取编辑器里面的值(内容),如下:         KindEditor.ready(function (K) { ...

  7. Vertica 6.1不完全恢复启动到LGE方法

    环境:RHEL6.2 + Vertica 6.1.3-7 确定所有节点的vertica进程都停掉(包括agent和python),如果有运行的,停止它或者杀掉它. 确定所有节点的spread进程都正常 ...

  8. WCF备忘录一:服务端实例的生命周期

    示例代码下载地址:WCFDemo1Day 概述 客户端向WCF服务发出请求后,服务端会实例化一个Service对象(实现了契约接口的对象)用来处理请求,实例化Service对象以及维护其生命周期的方式 ...

  9. Visual Studio (VSIX,项目模板 )制作

    下载Vsiual Studio 2012 SDK 下载地址:http://www.microsoft.com/en-us/download/details.aspx?id=30668 提示:一定要注意 ...

  10. Yii2.X 多语言-类图