轉載自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 456789
code
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個版本。 祝玩得開心!