面对软件错误构建可靠的分布式系统_笔记13

来源:互联网 发布:法兰绒哪个牌子好 知乎 编辑:程序博客网 时间:2024/05/29 14:34
6.5通用监督者Supervisor
gen_sup
6.5.1通用监督者
(1)supervisor:start_link(Name1, Mod, Arg) -> Result
(2)Mod:init(Arg) -> SupStrategy
    SupStrategy监督树,参见后面例子
 

-module(thesis_simple_sup).
-behaviour(supervisor).
-export([start/0, init/1]).

start() ->
 supervisor:start_link({local, thesis_simple_sup}, ?MODULE, nil).
 
init(_) ->
 {ok,
  {%%one_for_one:或型监督树,如果1000秒内被监督者重启超过5次,则监督者本身也错误

    {one_for_one, 5, 1000},  
   [
    {packet, %%被监督节点名称,要树内唯一
     {thesis_packet_assembler, start,[]}, %%被监督者模块、启动命令和参数

      %%permanent表示如果出错则自动重启,500指关停协议中Timer=500ms,worker指工作进程,最后是模块名称  
     permanent, 500, worker, [thesis_packet_assembler]}, 
    {server,
     {thesis_kv, start, []},
     permanent, 500, worker,[thesis_kv]},
    {logger,
     {thesis_simple_logger, start, []},
     permanent, 500, worker, [thesis_simple_logger]
    }
   ]
  }}. 

 
监督者通过调用shutdown(Pid,How)终止一个工作者,遵从停止协议:shutdown protocol
    shutdown(Pid, brutal_kill) ->  %%无条件杀死Pid进程
        exit(Pid, kill);
    shutdown(Pid, infinity) ->       %%发送shutdown消息,并等待回应
        exit(Pid, shutdown),
        receive
            {'EXIT',Pid, shutdown} -> true
        end;
    shutdown(Pid, Time) ->        %%发送shutdown消息,并等待回应,如果超时则无条件杀死,前面例子中,就是500ms
        exit(Pid, shutdown),
        receive
            {'EXIT', Pid, shutdown} -> true
        after Time ->
            exit(Pid, kill)
        end.
 
eg:将前面几个模块作为工作进程

-module(thesis_simple_sup).
-behaviour(supervisor).
-export([start/0, init/1]).

start() ->
 supervisor:start_link({local, thesis_simple_sup}, ?MODULE, nil).
 
init(_) ->
 {ok,
  {{one_for_one, 5, 1000},
   [
    {packet,
     {thesis_assember, start,[]},
     permanent, 500, worker, [thesis_assember]},
    {server,
     {thesis_kv, start, []},
     permanent, 500, worker,[thesis_kv]},
    {logger,
     {thesis_logger, start, []},
     permanent, 500, worker, [thesis_logger]} 
   ]
  }}. 

 
6.6通用应用的原理
负责打包、安装。没有Mod的回调函数,由应用描述文件.app,定义
6.6.1通用应用API
*.app
{application, Application,
    [ {description,  Description},
      {vsn,            Vsn},
      {id,              Id},
      {modules,     [Module1,,,ModuleN]},
      {maxT,         MaxT},
      {registered,   [Name1,...NameN]},
      {applications, [Appl1,..ApplN]},
      {included_applications, [Appl1,,,,ApplN]},
      {evn,            [{Par1,Val1},,,,{ParN,ValN}]},
      {mod,            {Module, StartArgs}},
      {start_phases, [{Phase1,PhaseArgs1],,,,{PhaseN,PhaseArgsN}]}]}.
    均是可选项
6.6.2通用应用的例子
thesis_simple.app
{application, 'thesis_simple',
    [ {description,  "A simple application"},
      {vsn,          "1.0"},
      {modules,     [thesis_simple,thesis_kv,thesis_logger,
           thesis_assember,thesis_simple_sup]},
      {maxT,         infinity},
      {registered,   [thesis_kv,my_simple_event_logger,my_simple_packet_assembler]},
      {applications, []},
      {included_applications, []},
      {evn,            []},
      {mod,            {thesis_simple, go}}]}.
定义thesis_simple.erl

-module(thesis_simple).
-behaviour(application).

-export([start/2]).
start(_,_) -> thesis_simple_sup:start().

 
启动:

1> application:start(thesis_simple, temporary).
Packet assembler starting
Key-Value server starting
Logger starting
ok
2> thesis_kv:store("yes","test").
ack
3> thesis_logger:log("hello").
ok
4> thesis_assember:send_header(2).
ok
5> thesis_assember:send_data("h") 
5> .
ok
6> thesis_assember:send_data("h").
Got data:hh
ok
7> application:stop(thesis_simple).

=INFO REPORT==== 29-Jan-2009::20:59:07 ===
    application: thesis_simple
    exited: stopped
    type: temporary
ok