[Erlang 0123] Erlang EPMD

简介:  epmd进程和Erlang节点进程如影随形,在Rabbitmq集群,Ejabberd集群,Couchbase集群产品文档中都会有相当多的内容讲epmd,epmd是什么呢?   epmd 是Erlang Port Mapper Daemon的缩写,全称足够明确表达它的功能了(相比之下,OTP就.
 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

 

或者使用启动参数
 
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里面就给出了使用配置文件的路子,只不过他是把这个配置放在专门的配置文件
如果这两个参数调整了,最好干掉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节点,从下面的输出信息,可以看到节点注册和注销注册的情况.
 
复制代码
 
[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
复制代码

 

 
 是不是比较迷惑里面的ALIVE2_REQ之类的是什么意思?这就要认真对照Erlang Distribution Protocol了,对照下面的图,如果有兴趣可以研究下协议,地址:  http://www.erlang.org/doc/apps/erts/erl_dist_protocol.html  
 
IMAGE MISSING
 
 
最后,这里有一个Golang的项目 Eclus-EPMD replacement in Go 有兴趣的可以看下,项目地址: https://github.com/goerlang/eclus  
 
参考资料:

本文转自博客园坚强2002的博客,原文链接:

http://www.cnblogs.com/me-sa/p/erlang-epmd.html如需转载请自行联系原博主。

目录
相关文章
|
JavaScript Java 测试技术
基于Java的图书馆管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的图书馆管理系统的设计与实现(源码+lw+部署文档+讲解等)
248 1
|
Web App开发 移动开发 前端开发
|
3月前
|
JSON 监控 Java
Elasticsearch 分布式搜索与分析引擎技术详解与实践指南
本文档全面介绍 Elasticsearch 分布式搜索与分析引擎的核心概念、架构设计和实践应用。作为基于 Lucene 的分布式搜索引擎,Elasticsearch 提供了近实时的搜索能力、强大的数据分析功能和可扩展的分布式架构。本文将深入探讨其索引机制、查询 DSL、集群管理、性能优化以及与各种应用场景的集成,帮助开发者构建高性能的搜索和分析系统。
328 0
|
11月前
|
存储 算法
​【Simulink】 风光储与电解制氢系统仿真模型(光伏耦合PEM制氢)
该仿真模型采用Simulink实现风光储与电解制氢系统的协同运行,涵盖光伏、风电、储能及电解槽制氢模块。光伏模块通过MPPT算法优化性能;储能系统采用双闭环控制维持电压稳定;风电模型利用永磁同步电机和变流器提高效率;电解槽制氢系统采用功率外环加电流内环控制实现恒功率制氢。仿真旨在整合风能、太阳能、储能和制氢技术,实现清洁能源高效利用,适用于研究和优化综合能源系统。提供2016b/2018b/2023b三个版本的模型,方便学习研究。
|
消息中间件 NoSQL 中间件
中间件发布-订阅模式(Pub/Sub)
【7月更文挑战第1天】
609 2
|
机器学习/深度学习 人工智能 自然语言处理
基于Mamba架构的,状态空间音频分类模型AUM
【8月更文挑战第7天】随着AI技术的发展,音频分类在诸多领域变得至关重要。传统方法如CNN面临计算成本高的问题。新兴的Mamba架构,基于状态空间模型(SSM),展示出优秀性能。受此启发,研究者开发了Audio Mamba (AUM)模型,首个完全基于SSM且不依赖自注意力机制的音频分类模型。AUM利用SSM的高效性捕捉音频时频特征,大幅降低计算复杂度,尤其适合大规模数据。实验显示,AUM在多个任务上的表现与先进自注意力模型相当甚至更好。尽管如此,AUM在复杂任务及泛化能力方面仍存在讨论空间。[论文](https://arxiv.org/abs/2406.03344)
446 1
|
安全 Linux 网络安全
在Linux中,什么是双因素认证(2FA)?
在Linux中,什么是双因素认证(2FA)?
|
TensorFlow 算法框架/工具 计算机视觉
ResNet实战:tensorflow2.0以上版本,使用ResNet50实现图像分类任务
ResNet实战:tensorflow2.0以上版本,使用ResNet50实现图像分类任务
1052 0
|
Go 调度 云计算
为什么我们放弃了Erlang技术栈
结合小博无线技术团队的具体经验,深入讨论了Erlang技术栈在云计算环境中所遇到的问题。
13046 2

热门文章

最新文章