erlang节点通信

Eerlang l与节点互连,断开,监控

之前记录过 [Erlang 0005] net_kernel:monitor_nodes 订阅node连接\断开消息 , 魔鬼在于细节(Devils are in the details),这个模块还是有一些细节要注意,特别是官方文档上语焉不详的问题.先从net_kernel的几个小功能开始:

net_kernel小功能

  1. 如果erlang vm启动的时候没有指定name,使用net_kernel可以在运行时指定

Eshell V5.9 (abort with ^G)
1> net_kernel:start([test@nimbus]).
{ok,<0.34.0>}
(test@nimbus)2>

  1. 判断当前是不是longname

(d@zen.com)3> net_kernel:longnames().
true

  1. 文档中提到 net_kernel:connect_node的返回值: returned ignored if the local node is not alive.

“local node is not alive” 说的是net_kernel没有启动的情况:
Eshell V5.9 (abort with ^G)
1> net_kernel:connect_node(a.zen.com).
ignored
2>

  1. In a distributed Erlang system, it is sometimes useful to connect to a node without also connecting to all other nodes. 要实现这个,节点启动的时候添加 -hidden [REF]

  2. 限定指定节点可以连通 net_kernel:allow(Nodes)

下面的几个问题就稍微复杂一些了,都是一些细节的问题,平时不注意可能就成了大坑.

主动断开连接

net_kernel模块导出了一个disconnect方法用来主动断开与指定节点的连接.比如可以 [net_kernel:disconnect(X) || X <- nodes() – [List_of_wanted_nodes]]. 这样批量断开一批连接.

下面的情况是a,b,c连通,然后a节点主动断开与b的连接,可以看到节点之间的关系变成了下图的关系:

[root@nimbus ligaoren]# erl -setcookie abc -name a@zen.com
Erlang R15B (erts-5.9) [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9 (abort with ^G)
(a@zen.com)1> net_adm:ping(c@zen.com).
pong
(a@zen.com)2> net_adm:ping(b@zen.com).
pong
(a@zen.com)3> nodes().
[‘c@zen.com’,‘b@zen.com’]
(a@zen.com)4> net_kernel:disconnect(b@zen.com).
true
(a@zen.com)5> nodes().
[‘c@zen.com’]
(a@zen.com)6>

[root@nimbus ligaoren]# erl -setcookie abc -name b@zen.com
Erlang R15B (erts-5.9) [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9 (abort with ^G)
(b@zen.com)1> nodes().
[‘c@zen.com’]
(b@zen.com)2>

[root@nimbus ligaoren]# erl -setcookie abc -name c@zen.com
Erlang R15B (erts-5.9) [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9 (abort with ^G)
(c@zen.com)1> nodes().
[‘a@zen.com’,‘b@zen.com’]
(c@zen.com)2> nodes().
[‘a@zen.com’,‘b@zen.com’]
(c@zen.com)3>

不自动连接

只要是涉及到引用另外的节点,比如rpc:call, 当前节点就会自动连接该节点,比如下面: 

Eshell V5.9 (abort with ^G)
(b@zen.com)1> rpc:call(a@zen.com,erlang,now,[]).
{1356,605316,345986}
(b@zen.com)2> nodes().
[‘a@zen.com’]
(b@zen.com)3>

如果要取消这个自动连接的行为可以使用dist_atuo_connect 参数,注意这里文档里面有个错误指定的参数不是false,是nerver.dist_auto_connect这个参数只接收两个值nerver(不自动连接) 和 once (自动连接,默认值).其它的值都是无效的. 如果想要连接到别的节点,就需要主动调用net_kernel:connect_node方法.

下面的测试,我们首先启动一个a@zen.com节点,erl -setcookie abc -name a@zen.com ,然后启动节点b@zen.com,注意启动参数中的dist_auto_connect选项:

[root@nimbus ligaoren]# erl -setcookie abc -name b@zen.com -kernel dist_auto_connect never
Erlang R15B (erts-5.9) [source] [64-bit] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9 (abort with ^G)
(b@zen.com)1> rpc:call(a@zen.com,erlang,now,[]).
{badrpc,nodedown}
(b@zen.com)2> net_kernel:connect_node(a@zen.com).
true
(b@zen.com)3> rpc:call(a@zen.com,erlang,now,[]).
{1356,605925,729498}
(b@zen.com)4> node().
‘b@zen.com’
(b@zen.com)5>

下面的情况是:(1) a@zen.com,c@zen.com 两个节点启动连通,(2) 然后启动b节点添加 dist_auto_connect never选项启动. (3) b@zen.com 节点主动连接节点a@zen.com 看下面的结果会发现,b@zen.com会收到一个异常消息: global: ‘b@zen.com’ failed to connect to ‘c@zen.com’ 在另外c@zen.com端也会接收类似的信息. (4)注意:b@zen.com在报了上面的错误之后,已经和c@zen.com连通了

%% Node a@zen.com
Eshell V5.9 (abort with ^G)
(a@zen.com)1> net_adm:ping(c@zen.com).<

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值