Erlang节点互联失败缘由分析以及解决方案

转载自Erlang非业余研究node

今天和项仲在部署新系统的时候发现节点间ping不成功的状况,相似shell

1> net_adm:ping('xx@ip1').      
pang服务器

因为这个问题比较广泛,我就记录下一步步的排除步骤.cookie

首先从原理上分析下!因为erlang节点间通信是透过tcp来进行的,因此咱们确保如下几点:    
1. 确保网络链接是通的,能够透过ping来查看。    
2. 确保网络链接上tcp是能够通的,能够透过netcat在二个节点所在的机器上分别开个服务器端和客户端进行验证。    
3. 确保端口是防火墙友好的。erlang的节点是登记在epmd服务上的,因此4369端口要能访问,其次节点的动态端口是能够访问的。网络

epmd -names      
epmd: up and running on port 4369 with data:      
name xx at port 46627      
async

一样能够用netcat来验证。    
4. erlang节点的cookie是同样的,能够透过setcookie来解决。tcp

这几点确认无误后,就能够开始排查问题了。    
首先交代下环境,二台机器IP分别是10.1.150.12,10.232.31.89, 上面分别运行Erlang版本R16B和R14B04,cookie统一设置为456789。    
接着咱们来演习下,首先咱们10.1.150.12在节点A上起个节点’xx@10.1.150.12′,以下:函数

# erl -name xx@`hostname -i` -setcookie 456789code

Erlang R16B (erts-5.10) 1 [64-bit] [smp:24:24] [async-threads:0] [hipe] [kernel-poll:false]blog

Eshell V5.10  (abort with ^G)

(xx@10.1.150.12)1>

=ERROR REPORT==== 28-Mar-2012::13:25:42 ===

** Connection attempt from disallowed node 'yy@10.232.31.89' **

同时咱们在10.232.31.89上运行另一个节点’yy@10.232.31.89′进行节点间链接,以下:

$erl -name yy@`hostname -i` -setcookie 456789

Erlang R14B04 (erts-5.8.5) 1 [64-bit] [smp:16:16] [rq:16] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.5  (abort with ^G)

(yy@10.232.31.89)1>  net_adm:ping('xx@10.1.150.12').

pang

咱们看到节点没法互通,出错的缘由是”** Connection attempt from disallowed node ‘yy@10.232.31.89′ ** “.    
有提示消息就好办, 在otp源码目录下简单的运行:

# grep -rin "disallowed node" .

./lib/kernel/src/dist_util.erl:154:                   "disallowed node ~w ** ~n", [Node]),

./lib/kernel/src/dist_util.erl:603:                           "disallowed node ~w ** ~n", [NodeB]),

./lib/kernel/src/dist_util.erl:623:                           "disallowed node ~w ** ~n", [NodeB]),

./lib/kernel/src/net_kernel.erl:1149:                 "disallowed node ~w ** ~n", [Node]),

咱们能够看到有4个函数有可能打印这个语句,分别是:    
1. is_allowed %% check if connecting node is allowed to connect with allow-node-scheme    
2 .recv_challenge_reply %% wait for challenge response after send_challenge    
3. recv_challenge_ack    
4. setup %% Set up connection to a new node.

其中和被动链接相关的俄只有1,2,3这几种状况.

状况1: 节点间allow相关的东西能够参考这篇文章:Erlang如何限制节点对集群的访问之net_kernel:allow    
咱们来排除下allow致使问题的缘由,把allow设成[],容许任意节点访问:

2> net_kernel:allow([]).      
ok      
(xx@10.1.150.12)2>      
=ERROR REPORT==== 28-Mar-2012::13:36:09 ===      
** Connection attempt from disallowed node ‘yy@10.232.31.89′ **

很清楚,这样并无解决问题。

那就能够确定是第2,3个缘由了,回头来看下咱们的版本号:    
R14B04 和 R16B, 差了二个大版本, 这个是核心缘由。    
换成一样的版本的erlang问题应该解决!以下:

$erl -name yy@`hostname -i` -setcookie 456789

Erlang R16B (erts-5.10) 1 [64-bit] [smp:24:24] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.10  (abort with ^G)

(yy@10.232.31.89)1>  net_adm:ping('xx@10.1.150.12').

pong

看来确实解决了!

小结: Erlang版本不混用,即便混用最好不超过2个版本。    祝玩得开心!

相关文章
相关标签/搜索