%一),监控树原理 %监控树负责启动,停止和监控子进程。 %监控树最基本的功能是保持子进程是活动的, %如果子进程意外停止,则必须重启它。 % %需要监控的子进程通过子进程描述列表来确定。 %子进程启动的顺序是其在子进程描述列表中的顺序, %子进程停止的顺序和启动的顺序相反。 % % %二),监控树实例: %监控树的回掉模块启动子进程gen_server, %gen_server的回调模块见Gen_Server Behaviour节。 % -module(supervisor_behaviour). -behaviour(supervisor). -export([start_link/0]). -export([init/1]). start_link() -> supervisor:start_link(supervisor_behaviour, []). init(_Args) -> {ok, {{one_for_one, 1, 60}, [{gen_server_behaviour, {gen_server_behaviour, start_link, []}, permanent, brutal_kill, worker, [gen_server_behaviour]}]}}. %one_for_one监控树重启策略 %1,60定义了最大启动频率 %元组{gen_server_behaviour, ...}子进程描述列表. % % %三),监控树启动策略 %one_for_one:如果一个子进程中止,仅仅启动该子进程。 %one_for_many:如果一个子进程中止,先停止所有的其他子进程, %再启动所有的子进程,包括刚才中止的进程。 %rest_for_one:如果一个子进程中止,则先停止子进程描述列表中 %所有排在该中止进程后面的进程,然后再启动他们,包括中止的进程。 % % %四),启动频率的最大值 %监控树可以控制指定时间段内的最大重启次数。 %通过子进程描述列表里面的MaxR和MaxT指定。如下所示: %init(...) -> % {ok, {{RestartStrategy, MaxR, MaxT}, % [ChildSpec, ...]}}. %如果在MaxT秒的时间内,有多于MaxR次重启,则监控树停止所有的子进程以及 %监控树自己。监控树停止后,更高层次的监控树负责处理,重启或者停止。 % % %五),子进程描述列表 %以下是一个子进程的描述: %{Id, StartFunc, Restart, Shutdown, Type, Modules} % Id = term() % StartFunc = {M, F, A} % M = F = atom() % A = [term()] % Restart = permanent | transient | temporary % Shutdown = brutal_kill | integer() >=0 | infinity % Type = worker | supervisor % Modules = [Module] | dynamic % Module = atom() %1,Id是子进程的名字,用于监控树标识子进程。 %2,StartFunc指定了启动了子进程的方法调用,它是以模块-函数-参数列表 %的形式描述,监控树使用 apply(M, F, A)的方式来启动子进程。通常是: %supervisor:start_link,gen_server:start_link, %gen_fsm:start_link or gen_event:start_link %3,Restart定义了何时启动子进程 %permanent标示子进程总是会重启 %temporary标示子进程永远不会被重启 %transient标示只有该进程被异常中止时才重启,即中止原因不是normal, %shutdown或者{shutdown,Term} %4,Shutdown定义了子进程应该如何被停止 %brutal_kill表示子进程将会无条件停止,监控树使用exit(Child, kill)来停止它。 %一个超时整数表示监控树先使用exit(Child, shutdown)来停止进程, %然后等待子进程的退出信号,如果超时时间内没有接受到子进程的退出信号, %则监控树调用 exit(Child, kill)来停止子进程。 %如果子进程也是监控树,则应该设置成无穷大的整数,以便于子树有足够的时间来停止, %子进程是worker也是可以设置成无穷大。 %5,Type指定子进程是supervisor还是worker %6,Modules应该是一个Module的列表,如果子进程是supervisor, gen_server %或者gen_fsm,则Module应该是回调模块,如果子进程是gen_event,则 %Module是dynamic。 % %例子:启动event manager的子进程的描述的: %{error_man, % {gen_event, start_link, [{local, error_man}]}, % permanent, 5000, worker, dynamic} % %例子:子进程为监控树 %{sup, % {sup, start_link, []}, % transient, infinity, supervisor, [sup]} % % %六),启动监控树 %start_link() -> % supervisor:start_link(ch_sup, []). %start_link调用supervisor:start_link/2来启动监控树,第一个参数是回调模块, %第二个参数是传递給init方法的参数,init回调方法将会首先被调用,它返回 %{ok,StartSpec},StartSpet是启动描述,init被调用完成后,监控树将会启动所有 %的子进程, %supervisor:start_link/2启动的监控树没有注册,如果想注册到一个名字,则: %supervisor:start_link({local, Name}, Module, Args)或者 %supervisor:start_link({global, Name}, Module, Args) % % %七),动态添加子进程 %supervisor:start_child(Sup, ChildSpec), %Sup是监控树PID或者监控树的注册名,ChildSpec是子进程描述信息。 % % %八),动态停止子进程 %supervisor:terminate_child(Sup, Id) %supervisor:delete_child(Sup, Id) % %九),Simple-One-For-One监控树 %它是one_for_one监控树的简化版本,所有的子进程都是动态添加的, %实例: %-module(simple_sup). %-behaviour(supervisor). %-export([start_link/0]). %-export([init/1]). %start_link() -> % supervisor:start_link(simple_sup, []). %init(_Args) -> % {ok, {{simple_one_for_one, 0, 1}, % [{call, {call, start_link, []}, % temporary, brutal_kill, worker, [call]}]}}. %当该监控树启动时,它不会启动任何的子进程,添加子进程: %supervisor:start_child(Sup, List) % %十),停止监控树 %监控树通常是其他监控树的一部分,所以有父监控树负责停止该监控树。 %程序例子执行结果: %1> c(gen_server_behaviour). %{ok,gen_server_behaviour} %2> c(supervisor_behaviour). %{ok,supervisor_behaviour} %3> supervisor_behaviour.start_link(). %** exception error: bad function 'supervisor_b %4> supervisor_behaviour:start_link(). %{ok,} %5> gen_server_behaviour:call_type_one(100). %handle_call invoked,the argurment is:100 %handle_call %6>
Supervisor Behaviour监控树
最新推荐文章于 2024-10-05 22:04:33 发布
本文详细介绍了监控树的基本原理及其实现方式,包括监控树如何启动、停止子进程及其重启策略,并提供了具体的Erlang实现案例。

117

被折叠的 条评论
为什么被折叠?



