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. 你还可以再诡异点吗——SQL日志文件不断增长

    前言 今天算是遇到了一个罕见的案例. SQL日志文件不断增长的各种实例不用多说,园子里有很多牛人有过介绍,如果我再阐述这些陈谷子芝麻,想必已会被无数次吐槽. 但这次我碰到的问题确实比较诡异,其解决方式 ...

  2. 那些年黑了你的微软BUG

    本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 前言 炎炎夏日,朗朗乾坤,30℃ 的北京,你还在 Coding 吗? 整个 7 月都在忙项目,还加了 ...

  3. Windows 2008 - 由于管理员设置的策略,该磁盘处于脱机状态

    http://blog.sina.com.cn/s/blog_59cc90640102x8m4.html 查看原文:https://www.bxl.me/9279.html准备使用云主机挂机的时候呢出 ...

  4. Entity Framework 6 Recipes 2nd Edition(9-6)译->管理断开时的并发

    9-6. 管理断开时的并发 问题 想要确保只接受在WCF客户端并发令牌未被修改的实体. 解决方案 我们有一个如Figure 9-6所示的模型. Figure 9-6订单实体模型 我们想通过WCF服务来 ...

  5. seajs的使用

    写在前面 seajs是什么? Seajs是一个js文件加载器. 遵循 CMD 规范模块化开发,依赖的自动加载.配置的简洁清晰. 用于Web开发的模块加载工具,提供简单.极致的模块化体验 一:使用 文件 ...

  6. 【译】Unity3D Shader 新手教程(4/6) —— 卡通shader(入门版)

    本文为翻译,附上原文链接. 转载请注明出处--polobymulberry-博客园. 暗黑系 动机 如果你满足以下条件,我建议你阅读这篇教程: 你想了解更多有关表面着色器的细节知识. 你想实现一个入门 ...

  7. iOS APP 如何做才安全

    本来 写了一篇<iOS 如何做才安全--逆向工程 - Reveal.IDA.Hopper.https抓包 等>,发现文章有点杂,并且“iOS 如何做才安全”这部分写的越来越多,觉得 分出来 ...

  8. ASP.NET MVC5+EF6+EasyUI 后台管理系统(21)-权限管理系统-跑通整个系统

    系列目录 这一节我们来跑通整个系统,验证的流程,通过AOP切入方式,在访问方法之前,执行一个验证机制来判断是否有操作权限(如:增删改等) 原理:通过MVC自带筛选器,在筛选器分解路由的Action和c ...

  9. 仅此一文让你明白ASP.NET MVC原理

    ASP.NET MVC由以下两个核心组成部分构成: 一个名为UrlRoutingModule的自定义HttpModule,用来解析Controller与Action名称: 一个名为MvcHandler ...

  10. MFC背景透明

    # 一: # typedef BOOL (WINAPI *lpfnSetLayeredWindowAttributes)(HWND hWnd, COLORREF crKey, BYTE bAlpha, ...