5.集群

来源:互联网 发布:两只重量级老虎知乎 编辑:程序博客网 时间:2024/06/06 03:20

  关于erlang的多节点通信,可以默认所有集群中的节点都运行在一个被信任和可靠的网络中,连通的节点间可以直接进行内部调用。

  下面通过一个简单的例子说明如何进行节点间的连接。
  开启2个erl节点:
  erl -name node1@127.0.0.1  erl -name node2@127.0.0.1
  在shell中输入
  nodes().
  可以看到返回值为
  []
  这是因为当前无连通的节点。在shell1中执行
  net_adm:ping('node2@127.0.0.1').
  然后再执行
  nodes().
  这时看到输出结果为
  ['node2@127.0.0.1']
  这时node1和node2已经连通。关于net_adm该模块,可以查看官网的说明文档:http://erlang.org/doc/man/net_adm.html
  为了安全性,防止别人也可以直接连上你的节点,我们一般需要加上cookie,当cookie不匹配时无法连通。下面是示例:
  erl -name node1@127.0.0.1 -setcookie demo  erl -name node2@127.0.0.1 -setcookie demo  erl -name node3@127.0.0.1
  启动3个shell后进行连通,可以看到node3无法加入node1或node2。
  现在我们把3个节点都连通:
  erl -name node1@127.0.0.1 -setcookie demo  erl -name node2@127.0.0.1 -setcookie demo -eval "net_adm:ping('node1@127.0.0.1')"  erl -name node3@127.0.0.1 -setcookie demo -eval "net_adm:ping('node1@127.0.0.1')"
  可以看到,node2和node3都连向node1,但我们在node3却发现node2节点也被连上了(在node2上也发现node3也被连接上了),这是因为集群中的节点都是互通的,一个新加入的节点会跟集群中的节点都进行连通。如果不希望自动连通,我们可以把node1设为孤立节点:
  erl -name node1@127.0.0.1 -setcookie demo -connect_all false
  这时再重启节点,可以发现只有node1连通了node2、node3,而node2和node3只连上了node1。
  连通之后,节点之间的互相调用就变成很简单了,下面有个简单的例子:
-module(t).-behaviour(gen_server).%% gen_server callbacks-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).-export([start/1,get/0]).start(N) ->    gen_server:start({local, ?MODULE}, ?MODULE, [N], []).get() ->    gen_server:call(?MODULE, get).init([N]) ->    {ok, N}.handle_call(get, _From, Status) ->    {reply, Status, Status};handle_call(_Event, _From, Status) ->    {reply, ok, Status}.handle_cast(_Event, Status) ->    {noreply, Status}.handle_info(_Event, Status) ->    {noreply, Status}.terminate(_Reason, _Status) ->    ok.code_change(_OldVsn, Status, _Extra) ->    {ok, Status}.
然后我们的启动命令也稍做一下修改:
erl -name node1@127.0.0.1 -setcookie demo -connect_all false -eval "t:start(1)"erl -name node2@127.0.0.1 -setcookie demo -eval "net_adm:ping('node1@127.0.0.1'),t:start(2)"erl -name node3@127.0.0.1 -setcookie demo -eval "net_adm:ping('node1@127.0.0.1'),t:start(3)"
这样我们在node1的shell中,执行t:get().可以看到结果是1,而执行rpc:call('node2@127.0.0.1', t, get, []).看到结果是2,执行rpc:call('node3@127.0.0.1', t, get, []).看到结果是3(当然,执行rpc:call('node1@127.0.0.1', t, get, []).看到结果是1)。
0 0
原创粉丝点击