Erlang節點間ping失敗原因分析
今天和項仲在部署新系統的時候發現節點間ping不成功的情況,類似
1> net_adm:ping(‘xx@ip1′).
pang
這個問題比較普遍,我就記錄下一步步的排除步驟.
首先從原理上分析下!由于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
…
同樣可以用netcat來驗證。
4. erlang節點的cookie是一樣的,可以透過setcookie來解決。
這幾點確認無誤后,就可以開始排查問題了。
交代下環境,二臺機器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 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) (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]),
我們可以看到有3個函數有可能打印這個語句,分別是:
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
節點間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問題解決!如下:
小結: Erlang版本不混用,即使混用最好不超過2個版本。
【編輯推薦】