Erlang節(jié)點(diǎn)間ping失敗原因分析
今天和項(xiàng)仲在部署新系統(tǒng)的時候發(fā)現(xiàn)節(jié)點(diǎn)間ping不成功的情況,類似
1> net_adm:ping(‘xx@ip1′).
pang
這個問題比較普遍,我就記錄下一步步的排除步驟.
首先從原理上分析下!由于erlang節(jié)點(diǎn)間通訊是透過tcp來進(jìn)行的,所以我們確保以下幾點(diǎn):
1. 確保網(wǎng)絡(luò)連接是通的,可以透過ping來查看。
2. 確保網(wǎng)絡(luò)連接上tcp是可以通的,可以透過netcat在二個節(jié)點(diǎn)所在的機(jī)器上分別開個服務(wù)器端和客戶端進(jìn)行驗(yàn)證。
3. 確保端口是防火墻友好的。erlang的節(jié)點(diǎn)是登記在epmd服務(wù)上的,所以4369端口要能訪問,其次節(jié)點(diǎn)的動態(tài)端口是可以訪問的。
epmd -names
epmd: up and running on port 4369 with data:
name xx at port 46627
…
同樣可以用netcat來驗(yàn)證。
4. erlang節(jié)點(diǎn)的cookie是一樣的,可以透過setcookie來解決。
這幾點(diǎn)確認(rèn)無誤后,就可以開始排查問題了。
交代下環(huán)境,二臺機(jī)器IP分別是10.1.150.12,10.232.31.89, 上面分別運(yùn)行Erlang版本R16B和R14B04,cookie統(tǒng)一設(shè)置為456789。
我們來演習(xí)下,首先我們10.1.150.12在節(jié)點(diǎn)A上起個節(jié)點(diǎn)’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上運(yùn)行另外一個節(jié)點(diǎn)’yy@10.232.31.89′進(jìn)行節(jié)點(diǎn)間連接,如下:
$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
我們看到節(jié)點(diǎn)無法互通,出錯的原因是”** Connection attempt from disallowed node ‘yy@10.232.31.89′ ** “.
在otp源碼目錄下簡單的運(yùn)行:
# 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個函數(shù)有可能打印這個語句,分別是:
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
節(jié)點(diǎn)間allow相關(guān)的東西可以參考這篇文章:Erlang如何限制節(jié)點(diǎn)對集群的訪問之net_kernel:allow
我們來排除下allow導(dǎo)致問題的原因,把a(bǔ)llow設(shè)成[],允許任意節(jié)點(diǎn)訪問:
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問題解決!如下:
小結(jié): Erlang版本不混用,即使混用最好不超過2個版本。
【編輯推薦】