惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
IT之家
IT之家
博客园_首页
Hugging Face - Blog
Hugging Face - Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
美团技术团队
小众软件
小众软件
博客园 - 叶小钗
WordPress大学
WordPress大学
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 三生石上(FineUI控件)
罗磊的独立博客
博客园 - Franky
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Last Week in AI
Last Week in AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
月光博客
月光博客
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
人人都是产品经理
人人都是产品经理

博客园 - 坚强2002

[Erlang 0129] Erlang 杂记 VI Graphviz绘制百家争鸣图 [Erlang 0128] Term sharing in Erlang/OTP 下篇 [Erlang 0127] Term sharing in Erlang/OTP 上篇 Elixir 1.0 Release [Erlang 0126] 我们读过的Erlang论文 读几首诗 [Erlang 0125] Know a little Erlang opcode "Becoming Functional" 阅读笔记+思维导图 [Erlang 0124] Erlang Unicode 两三事 - 补遗 [Erlang 0122] Erlang Resources 2014年1月~6月资讯合集 [Erlang 0121] 当我们谈论Erlang Maps时,我们谈论什么 Part 3 [Erlang 0120] Know a little Core Erlang [Erlang 0119] Erlang OTP 源码阅读指引 [Erlang 0118] Erlang 杂记 V [Erlang 0117] 当我们谈论Erlang Maps时,我们谈论什么 Part 2 [Erlang 0116] 当我们谈论Erlang Maps时,我们谈论什么 Part 1 致鸡鸣狗盗 一个技术人的知识管理方法论
[Erlang 0123] Erlang EPMD
坚强2002 · 2014-07-03 · via 博客园 - 坚强2002

 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 4369 with data:
name ns_1 at port 21101
name babysitter_of_ns_1 at port 21100
name ligaoren at port 51056

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

[root@nimbus data2]# erl -name test@nimbus -setcookie 1234 
[root@nimbus ~]# 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

或者使用启动参数

或者

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

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

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

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

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

如何让epmd使用指定端口

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

ERL_EPMD_ADDRESS=127.0.0.1 ERL_EPMD_PORT=8384 epmd -daemon 

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

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

 
[root@Slave4 ~]#
[root@Slave4 ~]# 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

IMAGE MISSING

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

参考资料:

发表于 2014-07-03 22:34  坚强2002  阅读(16293)  评论()    收藏  举报

Powered By 博客园