net_adm:ping失败非常奇怪

时间:2018-11-19 08:42:18

标签: erlang cluster-computing erlang-shell erlang-ports

亲爱的

我遇到关于Erlang集群的问题。在集群工作了很长时间之后的一天(一天),我无法再与集群中的特定节点(例如,SickNode @ X.X.X.X)建立任何连接,net_adm:ping(SickNode@X.X.X.X)返回一个紧急答案。甚至使用:

erlang -name abc@X.X.X.X -setcookie MYCOOKIE -remsh SickNode@X.X.X.X

也返回失败结果。

奇怪的是, SickNode@X.X.X.X在群集中的其他节点上运行良好当新节点加入群集并ping通到SickNode时,问题就刚刚发生。

这里没有任何防火墙,因为集群中的所有节点都运行良好。有没有人遇到这种糟糕的情况? Erlang对于群集使用而言不稳定吗?

PS:我在Centos 6.8上使用Erlang / OTP 20

非常感谢!

1 个答案:

答案 0 :(得分:2)

这不是直截了当的答案,而是重述您问题的理论和方法。 这很复杂,因为它涉及多个节点,但是让我们看看是否可以关注我。

TL; DR: SickNode@X.X.X.X 在连接到集群后更改了其cookie。

所以,这就是我所做的…… 首先,在终端上,我以Cookie node1开始x

$ erl -name node1 -setcookie x
(node1@my.computer)1> 

然后,在另一个终端上,我以Cookie node2开始x,将其连接到node1并将其cookie更改为y

$ erl -name node2 -setcookie x
(node2@my.computer)1> net_adm:ping('node1@my.computer').
pong
(node2@my.computer)2> erlang:set_cookie(node(), 'y').
true
(node2@my.computer)3>

然后,在另一个终端中,我以Cookie node3开始x并ping node1(这也导致尝试连接到node2,正如您将看到的下面),然后明确地尝试连接到node2

$ erl -name node3 -setcookie x
(node3@my.computer)1> net_adm:ping('node1@my.computer').
pong
(node3@my.computer)2>
=WARNING REPORT==== 21-Nov-2018::15:09:07 ===
global: 'node3@my.computer' failed to connect to 'node2@my.computer'

=ERROR REPORT==== 21-Nov-2018::15:09:26 ===
** Connection attempt from disallowed node 'node2@my.computer' **
(node3@my.computer)2> net_adm:ping('node2@FERNANDO-BENAVIDES.Conyfero').
pang

到目前为止发生了什么?好吧,由于node1的cookie是x,而node3的cookie也是x,所以他们可以连接。 node2仍连接到node1,但是由于cookie存在ynode3无法连接到它。

Erlang尝试建立一个完全连接的节点网格,因此当您连接到其中一个节点时,它会自动尝试将您连接到所有其他节点。

但是我想做得透彻一些,所以我从node2 ping node3,并按预期得到了pang。此外,这些消息还会在node2上弹出:

(node2@my.computer)3>
=ERROR REPORT==== 21-Nov-2018::15:09:07 ===
** Connection attempt from disallowed node 'node3@my.computer' **

=WARNING REPORT==== 21-Nov-2018::15:09:07 ===
global: 'node2@my.computer' failed to connect to 'node3@my.computer'

当然,当我尝试从node3 ping node2时……

(node2@my.computer)3> net_adm:ping('node3@my.computer').
pang

但是...如果我尝试ping node1 ...

(node2@my.computer)4> net_adm:ping('node1@my.computer').
pong

这是因为它们已经连接,并且Erlang仅在初始握手时验证cookie的共享。

最后,如果我尝试从node1 ping节点,则会得到预期的结果……

(node1@my.computer)1> net_adm:ping('node2@my.computer').
pong
(node1@my.computer)2> net_adm:ping('node3@my.computer').
pong
(node1@my.computer)3>

希望这会有所帮助。