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個版本。    祝玩得開心!

相關文章
相關標籤/搜索