1.监控树
监控树是一种由进程组成的树形结构。树的上级进程(监控器)监视着下级进程(工作器), 如果下级进程挂了就会重启它们。
监控树有两种。
1.一对一监控树:
在一对一监控里,如果某个工作器崩溃了,就会被监控器重启。
2.一对多监控树:
在一对多监控里,如果任何一个工作器崩溃了,所有工作进程都会被终止(通过调用相应回调模块里的terminate/2函数)然后重启。 监控器是用OTP supervisor行为创建的。这个行为用一个回调模块作为参数,里面指定了监控策略以及如何启动监控树里的各个工作进程。
创建一个监控树来监控质数和面积服务器始终保持运行
代码如下
-module(sellaprime_supervisor).
-behaviour(supervisor).
-export([start/0, start_in_shell_for_testing/0, start_link/1, init/1]).
start() ->
spawn(fun() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, _Arg = [])
end).
start_in_shell_for_testing() ->
{ok, Pid} = supervisor:start_link({local, ?MODULE}, ?MODULE, _Arg = []),
unlink(Pid).
start_link(Args) ->
supervisor:start_link({local, ?MODULE}, ?MODULE, Args).
init([]) ->
gen_event:swap_handler(alarm_handler,
{alarm_handler, swap},
{my_alarm_handler, xyz}),
{ok, {{one_for_one, 3, 10},
[{tag1,
{area_server, start_link, []},
permanent,
10000,
worker,
[area_server]},
{tag2,
{prime_server, start_link, []},
permanent,
10000,
worker,
[prime_server]}
]}}.
主要重点是init()的返回部分
这个数据结构定义了一种监控策略。
Worker的格式是下面这种元组:
{Tag, {Mod, Func, ArgList}},
Restart,
Shutdown,
Type,
[Mod1]}
Tag
这是一个原子类型的标签,将来可以用它指代工作进程。
{Mod, Func, ArgList}
它定义了监控器用于启动工作器的函数,将被用作apply(Mod, Fun, ArgList)的参数。
Restart = permanent | transient | temporary
permanent(永久)进程总是会被重启。transient(过渡)进程只有在以非正常退出值
终止时才会被重启。temporary(临时)进程不会被重启。
Shutdown
这是关闭时间,也就是工作器终止过程允许耗费的最长时间。如果超过这个时间,工作
进程就会被杀掉。(还有其他值可用,参见supervisor的手册页。)
Type = worker | supervisor
这是被监控进程的类型。可以用监控进程代替工作进程来构建一个由监控器组成的树。
[Mod1]
如果子进程是监控器或者gen_server行为的回调模块,就在这里指定回调模块名。