注册

erlang集群常识(其实只是关于node的基本知识)

读书笔记 读书笔记 依旧是那本erlang/OTP并发编程实战 买了纸质书懊悔不已 已打算再买图灵的电子版了...哎~~

在本机上建立一个node网络 和好几台计算机分别建一个node然后连接差不多是一样的

1.建立节点
要建立节点是很简单的(以下的实验都是在win下做得):
分别在三个cmd下输入
Java代码

erl -sname a
erl -sname b
erl -sname c 当然还可以输入erl -name a 但在win下(至少是我这)会出错误:

写道

{error_logger,{{2013,7,10},{21,25,11}},"Can't set long node name!\nPlease check your configuration\n",[]}
{error_logger,{{2013,7,10},{21,25,11}},crash_report,[[{initial_call,{net_kernel,init,}},{pid,<0.20.0>},{registered_name,[]},{error_info,{exit,{error,badarg},[{gen_**,init_it,6,},{proc_l
ib,init_p_do_apply,3,}]}},{ancestors,},{messages,[]},{links,},{dictionary,},{trap_exit,true},{status,running},{heap_size,6772},{stack_size,27},{reduc
tions,1921}],[]]}
{error_logger,{{2013,7,10},{21,25,11}},supervisor_report,[{supervisor,{local,net_sup}},{errorContext,start_error},{reason,{'EXIT',nodistribution}},{offender,[{pid,undefined},{name,net_kernel},{mfargs,{net_kernel,start_link,[]}
},{restart_type,permanent},{shutdown,2000},{child_type,worker}]}]}
{error_logger,{{2013,7,10},{21,25,11}},supervisor_report,[{supervisor,{local,kernel_sup}},{errorContext,start_error},{reason,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}},{offender,[{pid,undefined},{name,net_sup},{m
fargs,{erl_distribution,start_link,[]}},{restart_type,permanent},{shutdown,infinity},{child_type,supervisor}]}]}
{error_logger,{{2013,7,10},{21,25,11}},crash_report,[[{initial_call,{application_**,init,}},{pid,<0.9.0>},{registered_name,[]},{error_info,{exit,{{shutdown,{failed_to_start_child,
net_sup,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}}},{kernel,start,[normal,[]]}},[{application_**,init,4,},{proc_lib,init_p_do_apply,3,}]}},{ancestors,},{messages,},{links,},{dictionary,[]},{trap_exit,true},{status,running},{heap_size,376},{stack_size,27},{reductions,117}],[]]}
{error_logger,{{2013,7,10},{21,25,11}},std_info,[{application,kernel},{exited,{{shutdown,{failed_to_start_child,net_sup,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}}},{kernel,start,[normal,[]]}}},{type,permanent}]}
{"Kernel pid terminated",application_controller,"{application_start_failure,kernel,{{shutdown,{failed_to_start_child,net_sup,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}}},{kernel,start,[normal,[]]}}}"}

Crash dump was written to: erl_crash.dump
Kernel pid terminated (application_controller) ({application_start_failure,kernel,{{shutdown,{failed_to_start_child,net_sup,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}}},{k过程如下


8VKL_AVV_}`2M]8MCFEK][8.jpg



2.节点互联
接下去让节点间互联:
节点间:
Java代码
nodes/0 %获得和当前node连接的所有node
net_adm:ping/1 %ping一个node 成功后就返回pong 失败返回pang(也许还有出错信息)

屏幕快照 2015-04-10 上午10.46.31.png



图中用a去连b 再用a去连c 然后就可以看到a b c都**了
erlang 默认下用的是全连接的方式 如图:


QQ20150414-1@2x.png



3.cookie
cookie是保证连接顺利的一个重要因素
如果两个node的cookie相同 那么就可以连接(以上的abc都在本机中 c:\user\dell\.erlang.cookie中)
如果cookie不相同 也可以设置一下 设置之后的node就可以连接
还是以上的图 我们让节点a退出(在abc互联下 如果不退出直接用auth:set_cookie/1改掉a的cookie 那a的连接还是保持的)
a退出后 只有bc保持互联
可以看到 bc 的cookie是:
'MGEHUYAYGOAWXUPWFKDN'a的:
Erlang代码

(a@dell-PC)6> q().
ok
(a@dell-PC)7>
C:\Users\dell>erl -sname a
Eshell V5.10.2 (abort with ^G)
(a@dell-PC)1> auth:set_cookie('abcdefg123456789').
true
(a@dell-PC)2> net_adm:ping('b@dell-PC').
pang
(a@dell-PC)3> 可见是pang 表示失败了
同时看一下b:
Erlang代码

(b@dell-PC)2> auth:get_cookie().
'MGEHUYAYGOAWXUPWFKDN'
(b@dell-PC)3>
=ERROR REPORT==== 10-Jul-2013::22:16:31 ===
** Connection attempt from disallowed node 'a@dell-PC' ** 不允许ab互联 当然 ac也不能互联了 现在能互联的只有 bc
这样可以保证节点之间的隔离 不至于发现一次误ping导致所有的节点都连在一起了

但如果一定要ab互联呢?? 这也是可以的
既可以从a 设置 也可以从b设置:
使用:
Erlang代码

auth:set_cookie/2 代码如下:
Erlang代码

(a@dell-PC)3> auth:set_cookie('b@dell-PC','MGEHUYAYGOAWXUPWFKDN').
true
(a@dell-PC)4> net_adm:ping('b@dell-PC').
pong
(a@dell-PC)5>
=ERROR REPORT==== 10-Jul-2013::22:20:20 ===
** Connection attempt from disallowed node 'c@dell-PC' **
(a@dell-PC)5>
=ERROR REPORT==== 10-Jul-2013::22:20:20 ===
** Connection attempt from disallowed node 'c@dell-PC' **
(a@dell-PC)5>
=ERROR REPORT==== 10-Jul-2013::22:20:20 ===
** Connection attempt from disallowed node 'c@dell-PC' **
(a@dell-PC)5>
=ERROR REPORT==== 10-Jul-2013::22:20:20 ===
** Connection attempt from disallowed node 'c@dell-PC' **
(a@dell-PC)5>
=ERROR REPORT==== 10-Jul-2013::22:20:20 ===
** Connection attempt from disallowed node 'c@dell-PC' **
(a@dell-PC)5>
=ERROR REPORT==== 10-Jul-2013::22:20:20 ===
** Connection attempt from disallowed node 'c@dell-PC' **
(a@dell-PC)5>
=ERROR REPORT==== 10-Jul-2013::22:20:20 ===
global: 'a@dell-PC' failed to connect to 'c@dell-PC' 代码的步骤是在a中设置一下b的cookie 让a的node可以认可b的node 这样ab就可以互联
然后a ping了一下b 可见pong 说明ping通了 但是产生了错误
错误时因为a和c不能连接 最开始bc是连接的 现在通过修改a让a认可b a和b之间可以互联 但是a和c之间并没有验证:

a 的nodes():
(a@dell-PC)5> nodes().



b的nodes():
(b@dell-PC)3> nodes().



c的nodes():
(c@dell-PC)2> nodes().
如图:

屏幕快照 2015-04-20 下午6.43.58.png



(为什么觉得和手工配路由有点像啊....)
也就是各种"全双工“的拓扑只要你想建就建得起来,....不过一般没那么无聊吧 汗....

以上说过如果已经连通了 修改cookie不对连接产生影响 验证如下:
Erlang代码
(b@dell-PC)3> nodes().

(b@dell-PC)4> auth:set_cookie('123456').
true
(b@dell-PC)5> net_adm:ping('a@dell-PC').
pong
(b@dell-PC)6> net_adm:ping('c@dell-PC').
pong 总结一下命令吧:
erl -sname 名字 %建立一个node

net_adm:ping/1 %ping一个node pong就连接 pang表失败

auth:get_cookie/1 %获得当前node的cookie值

auth:set_cookie/1 %修改当前的node的cookie值(已连接下不会断开和其他node的连接)

auth:set_cookie/2 %第一个参数是另外一个node(node和cookie都是原子 用' ')第二个参数是那个node的cookie 用来让不同cookie的两个node连接有错误一定要提啊...谢谢了

已邀请:

要回复问题请先登录注册