【问题标题】:Erlang - Nodes don't recognizeErlang - 节点无法识别
【发布时间】:2016-06-16 05:32:47
【问题描述】:

我正在尝试在 Erlang 中使用分布式编程。

但是我有一个问题,我无法让两个 Erlang 的节点通信。

我尝试将相同的原子放入“Magical cookies”中,但没有成功。

我尝试使用命令 net:ping(node),但响应很糟糕(没有重新配置另一个节点),或者使用了 nodes(),以查看我的第一个节点是否看到第二个节点,但它没有再次工作。

第一个和第二个节点是VMWare中的CentOS,在网络适配器中使用桥接。

我在虚拟机之间的 Erlang 之外输入了命令 ping,它们重新配置了每个虚拟机。

我启动第一个节点,但是第二个节点打开进程,却找不到节点pong。

(pong@localhost)8> tut17:start_pong().
true


(ping@localhost)5> c(tut17).
{ok,tut17}
(ping@localhost)6> tut17:start_ping(pong@localhost).
<0.55.0>

谢谢!

【问题讨论】:

  • 您将需要提供一些代码和上下文以获取帮助。
  • 您是否检查过防火墙配置和路由器(如果有)?
  • 你能从两个节点发布epdm -names吗?
  • 主机 1 epmd: up and running on port 4369 with data: name ping at port 33880 主机 2 epmd: up and running on port 4369 with data: name pong at port 59495
  • node(). 从两个节点上的 Erlang shell 返回什么?

标签: erlang distributed-computing


【解决方案1】:

A similar question here.

分发由名为Erlang Port Mapper Daemon 的守护程序提供。默认情况下,它侦听端口 4369,因此您需要确保在节点之间打开该端口。此外,每个启动的 Erlang VM 都会打开一个额外的端口来与其他 VM 通信。你可以用epmd -names看到这些端口:

g@someserv1:~ % epmd -names
epmd: up and running on port 4369 with data:
name hbd at port 22200

你可以通过telnet来检查端口是否打开,例如:

g@someserv1:~ % telnet 127.0.0.1 22200
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
^]
Connection closed by foreign host.

您可以将端口更改为您要检查的端口,例如4369,以及所需IP的IP。执行ping 是不够的,因为它使用自己的ICMP protocol,这与Erlang 发行版使用的TCP 通信不同,例如可能允许 ICMP,但可能会阻止 TCP。

编辑:

请按照本指南Distributed Erlang 以分布式模式启动 Erlang VM。然后你可以使用net_adm:ping/1从另一个节点连接到它,例如:

(hbd@someserv1.somehost.com)17> net_adm:ping('hbd@someserv2.somehost.com').
pong

只有epmd -names 才会在列表中显示已启动的 Erlang VM。

编辑2:

假设有主机 A 和 B。每台运行一个 Erlang 虚拟机。 epmd -names在每个主机上运行显示例如:

主持人 A:

epmd: up and running on port 4369 with data:
name servA at port 22200

主持人乙:

epmd: up and running on port 4369 with data:
name servB at port 22300

你需要能够做到:

在主机 A 上:

telnet HostB 4369
telent HostB 22300

在主机 B 上:

telnet HostA 4369
telnet HostA 22200

其中 HostA 和 HostB 是这些主机的 IP 地址(例如 HostA 是主机 A 的 IP,HostB 是主机 B 的 IP)。

如果 telnet 工作正常,那么您应该能够从一台主机到另一台主机执行 net_adm:ping/1,例如在主机 A 上,您将 ping 主机 B 的名称。该名称是命令 node(). 返回的名称。

【讨论】:

  • 我编辑了答案以添加如何正确启动 VM 节点的信息。 epmd -names 不显示 VM,除非它知道它,例如虚拟机已启动并可连接。请阅读指南以了解分发的工作原理,简而言之,Erlang VM 尝试与epmd 通信以在其中注册并发现其他节点。然后它为每个可以通过epmd 成功连接的虚拟机创建一个新端口。
  • 是的,我之前遵循了这个指南,但是没有用。 [erlang@localhost ~]$ epmd -names epmd: up and running on port 4369 with data: 我只有一个 4369 端口。我将我的 cookie 设置为同一个原子,但我的节点没有连接。
  • 4369 端口不能超过一个。epmd 在 4369 上运行,每个新启动的虚拟机都有自己的端口。你是如何启动你的虚拟机的,你在启动你的虚拟机时使用了哪些参数?在 Erlang shell 中执行 node(). 会得到什么?
  • 对不起,Amiramix。我在同一台主机上尝试过,但它适用于不同的主机(如 VMWare 中的 2 CentOS)。我想我必须做一些不同的事情。谢谢你帮助我!
  • 一次一步。您需要确定 epmd 是否可以在这些主机之间进行通信。您需要 1. 使用命令epmd -names 确定每个 Erlang VM 在哪个端口上侦听来自其他 Erlang VM 的连接。 2. 确定您是否可以从另一台主机远程登录到该端口。我将添加一个编辑来向您展示我的意思。
【解决方案2】:

您需要确保您的节点有一个节点名称,否则它们将无法连接。例如:

erl -sname somenode@node1

如果您使用单独的主机,那么您需要确保节点名称能够以某种方式解析为 IP 地址。一个简单的方法是使用 /etc/hosts。

# Append a similar line to the /etc/hosts file
10.10.10.10 node1

要获得更多有用的答案,您应该在尝试此操作时发布您在终端中看到的内容。


编辑

看起来您的 shell 自动选择“localhost”作为节点名称。您不能将消息发送到地址为“localhost”的另一台主机。在 shell 上指定名称时,请尝试使用 @ 语法来指定节点名称:

# On host 1:
erl -sname ping@host1

# On host 2
erl -sname pong@host2

然后编辑主机文件,让 host1 和 host2 解析到正确的 IP。

【讨论】:

  • 我编辑了我的问题,我正在尝试使用 Erlang quickstart 中的教程 ping pong。节点pong启动成功,但是节点ping不能和Pong节点通信。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-28
  • 1970-01-01
  • 2016-01-09
  • 1970-01-01
相关资源
最近更新 更多