两种分布模型
一.分布式Erlang
在分布式Erlang里,我们的程序会运行在不同的节点(Node)上,每个Node都是一个独立的虚拟机,安全性是比较低的,因为只要知道某个节点的名称和cookie就可以拥有这个节点的所有权限,这种模型通常运行在同一个局域网的集群上(虽然也可以在万维网上跑)
我们分4个步骤慢慢深入了解这种模型:
- 在常规的非分布式系统上编写和测试名称服务器
- 在一台机子两个节点上测试(局域网测试)
- 在万维网上测试
1.在常规的非分布式系统上编写和测试名称服务器
%this is a kvs nameServer
-module(kvs)
-export([]).
-compile(export_all).
start()->
register(kvs,spawn(fun()-> loop() end)).
rpc(Q)->
kvs ! {selft(),Q},
receive
{kvs,Reply}->
Reply
end.
store(Key,Value)->rpc({store,Key,Value}).
lookup(Key)->rpc{lookup,Key}.
loop()->
receive
{From,{store,Key,Value}}->
put(Key,Value),
From ! {kvs,true},
loop();
{From,{lookup,Key}}->
From ! {kvs,get(Key)},
loop()
end.
检查程序是否可运行:
1>kvs:start().
true
2>kvs:store({location,loop},"GuangZhou").
true
3>kvs:lookup({location,loop}).
{ok,"GuangZhou"}.
至此,第一阶段完成
2.在一台机子两个节点上测试(局域网测试)
(1). 启动一个节点
$ erl -sname server #以server为短名称启动一个erlang节点
(server@hostname) 1> kvs:start(). %这个hostname在linux中/etc/hostname设置 Window则在网络管理器设置,我这里的hostname用最特殊的一种表示:ip server@192.168.0.2
true
(2).在局域网内的一台机子启动另一个节点并调用rpc模块中的call函数,这里主要介绍这个函数
-spec rpc:call(node,Mod,Func,Args) when
node::一个节点名称 server@hostname 如果节点名称中含有非原子类型的符号,则加引号 'server@192.168.0.2'
Mod::模块名称 我们填kvs
Func::模块中函数名称 我们填store或者lookup
Args::参数列表
至此,第二阶段完成
3. 在万维网上测试
%其实和局域网大同小异,只是启动节点的时候都用-name 因为在不同的网络下
%另外互相连接的节点还要保证cookie是相同的 都使用 -setcookie xxx 这个xxx是原子类型
$ erl -name client -setcookie=abc
4.分布式编程的库和BIF
-spec spawn(Node,Func)->Pid
-spec spawn(Node,Mod,Func,Args)->Pid
-spec spawn_link(Node,Func)->Pid
-spec spawn_link(Node,Mod,Func,Args)->Pid
-spec disconnect_node(Node)-> bool() | ignored %强制断开与Node的连接
-spec monitor_node(Node,Flag)-> true when
Node::节点
Flag:: true | flase %true则开启,false则关闭
-spec node() -> Node
-spec(Arg)->Node when
Arg :: Pid | Port | Reference
-spec nodes()-> [Node] %返回与我们相连的所有节点的列表
-spec is_alive() -> bool()
{RegName,Node} ! Msg
二、.基于套接字的分布式模型
这种模型不如第一种强大,但是更安全。
暂时不写,等我读懂了lib_chan我再回来补上!
貌似就是中间人模式(MM)服务端和客户端都有自己的中间人,他们负责接收外部的消息,然后简单处理后发送给最终接收人,在$HOME/.erlang_config/lib_chan.conf中配置好启动的参数等
-module(mod_name_server).
-export([start_me_up/3]).
start_me_up(MM,_ArgsC,_ArgS) ->
loop(MM).
loop(MM)->
receive
{chan,MM,{store,K,V}}->
kvs:store(K,V),
loop(MM);
{chan,MM,{lookup,K}}->
MM ! {send,kvs:lookup(K)},
loop(MM);
{chan_close,MM}->
true
end
网友评论