erlang多node通信失败

Posted by Elton's Blog on November 5, 2012

在测试在本机部署多个node,实现多个node间的rpc调用和通信。

假设服务器端的程序如下:

-module (kvs).
-export ([start/0,store/2,lookup/1]).

start() -> register(kvs, spawn(fun() -> loop() end)).

store(Key, Value) -> rpc({store, Key, Value}).

lookup(Key) -> rpc({lookup, Key}).

rpc(Q) ->
	kvs ! {self(), Q},
	receive
		{kvs, Reply} ->
			Reply
	end.

loop() ->
	receive
		{From, {store, Key, Value}} ->
			put(Key, {ok, Value}),
			From ! {kvs, true},
			loop();
		{From, {lookup, Key}} ->
			From ! {kvs, get(Key)},
			loop()
	end.

在终端中执行

$ erl -sname gandalf
Erlang R15B02 (erts-5.9.2) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2  (abort with ^G)
([email protected])1> kvs:start().
true

启动另外一个终端,执行

$ erl -sname bilbo
Erlang R15B02 (erts-5.9.2) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2  (abort with ^G)
([email protected])1> rpc:call([email protected], kvs, store, [weather, fine]).
{badrpc,nodedown}

显示{badrpc,nodedown}。

测试

([email protected])3> net_adm:ping([email protected]).
pang

显示pang,表示不通,通的话应该是pong

直接在shell中ping主机名,发现

$ ping EltonMacBookPro
PING eltonmacbookpro.home (180.168.41.175): 56 data bytes
64 bytes from 180.168.41.175: icmp_seq=0 ttl=248 time=14.337 ms
64 bytes from 180.168.41.175: icmp_seq=1 ttl=248 time=16.196 ms
64 bytes from 180.168.41.175: icmp_seq=2 ttl=248 time=12.764 ms

不是本地地址,是公网地址。 所以在/etc/hosts中指定一下主机名对应的ip 127.0.0.1。

之后就一切正常了

([email protected])5> rpc:call([email protected],kvs,store,[weather, fine]).
true
([email protected])6> rpc:call([email protected],kvs,lookup,[weather]).     
{ok,fine}

如果在本地局域网多台机器上部署对应node,则需要将局域网的机器名在hosts中都设置对应的ip地址。 比如A机器机器名是ubuntu,部署服务端。现在要用B(机器名EltonMacBookPro)来远超调用A的函数。 可以在B中的/etc/hosts设置A的机器名的ip地址。如

192.168.1.39 ubuntu

在A中运行

$ erl -sname gandalf -setcookie abc
Erlang R15B02 (erts-5.9.2) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2  (abort with ^G)
([email protected])1> kvs:start().
true

在B中运行

$ erl -sname bilbo -setcookie abc
Erlang R15B02 (erts-5.9.2) [source] [64-bit] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.2  (abort with ^G)
([email protected])1> rpc:call([email protected],kvs,store,[weather,cold]).      
true
([email protected])2> rpc:call([email protected],kvs,lookup,[weather]).     
{ok,cold}