博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【整理】Erlang 中的 supervisor
阅读量:6700 次
发布时间:2019-06-25

本文共 3486 字,大约阅读时间需要 11 分钟。

【概况】

supervisor behaviour 是用来实现监控其他子进程的 supervisor 进程的模块;
 

子进程可以是另一个 supervisor 进程,也可以是一个 worker 进程;
 

worker 进程一般使用 gen_event,gen_fsm 或 gen_server behaviour 来实现
 
 

一个使用 supervisor behaviour 实现的 supervisor 有一个接口方法的标准集,包括跟踪和错误报告的功能;
 

supervisor 机制用来构建一个分层进程结构,称为 supervision tree,这是组织一个容错系统的好方式。
 


【原则】

supervisor 负责启动、停止和监控它的子进程;
 

supervisor 在必要时,通过重启它的子进程来使其保持活着;
 

supervisor 的子进程由称作子进程规范的列表进行定义;
 

当 supervisor 启动时,子进程按子进程规范列表中内容从左至右的顺序启动;
 

当 supervisor 终止时,会按子进程启动顺序的反顺序终止相应子进程。
 


【重启策略】

one_for_one
 

如果一个子进程停止,则只重启该子进程;
 

one_for_all
 

如果一个子进程停止,则所有其他子进程也停止,然后所有子进程重启;
 

rest_for_one
 

如果一个子进程停止,则启动顺序中在它之后的所有其他子进程也停止,然后停止的这些子进程重启;
 

simple_one_for_one 
 

一个简化的 one_for_one ,所有的子进程都是同样进程类型并且是动态添加的实例;
 


【最大重启频率】

supervisor 有一个自带的机制来限制给定时间内重启的次数;
 

如果在最近的 MaxT 秒之内有超过 MaxR 次数的重启,则 supervisor 停止它本身和它所有的子进程;
 

当 supervisor 停止后,下一个更高级别的 supervisor 将进行下一步动作,重启上述停止的 supervisor 或者终止本身;
 

重启机制的意图是防止一个进程由于某些原因重复性的死掉;
 


【子规范】

1
{Id, StartFunc, Restart, Shutdown, Type, Modules}
Id
 
用于 supervisor 内部识别子规范的名字;
 


StartFunc
 
定义了用来启动子进程的的方法,由三元组 {M, F, A} 来确定,其一般情况下调用的是 
supervisor:start_link
 
 
gen_server:start_link
 
gen_fsm:start_link
 
或 
gen_event:start_link
 
,或对上述函数的相应封装。 
 


Restart
 
定义了子进程什么时候重启:
 

  • permanent 表示子进程始终重启;
  • temporary 表示子进程决不重启;
  • transient 表示只有在子进程异常终止时才重启,即除了 normal 以外的终止原因;

Shutdown
 
定义了子进程怎样终止:
 

  • brutal_kill 表示子进程使用 exit(Child, kill) 来无条件的终止;
  • 一个整数 timeout 值表示 supervisor 通过调用 exit(Child, shutdown) 告诉子进程请终止自己,然后等待子进程返回退出信号;如果没有在指定的时间内接收到(来自子进程的) 退出信号,则使用 exit(Child, kill) 无条件终止子进程
  • 如果子进程是另一个 supervisor,则应该设置为 infinity 来给子树足够的时间来终止;

Type
 
指定子进程是一个 supervisor 还是一个 worker;
 


Modules
 
应该是一个 list,含有一个元素 [Module]。
 

如果子进程是一个 supervisor,或者子进程是 woker 且采用 gen_server 或 gen_fsm 行为模式实现,则 Modules 是 callback 模块的名字;
 

如果子进程是 worker 且采用 gen_event 行为模式实现,则 Modules 应该为 
dynamic
 
,该信息用来在升级和降级时供 release handler 使用;
 


【参数选择原则】

按照子进程规范启动的子进程,若是要求该子进程为任何时候均可访问的注册进程,则一般使用参数 permanent ;
 

按照子进程规范启动的子进程,若是要求该子进程终止之前不需要做任何清理工作,则不需要设置 timeout 值,可以设置为 brutal_kill
 

若是要求其终止之前做相应资源清理,则需要设置 timeout 超时值。 
 


【启动 supervisor】

1
supervisor:start_link(CallbackModuleName, InitCallbackParamList).
启动一个新的 supervisor 进程并链接到 OTP 系统的监督树中;
 

  • 第一个参数 callback 模块的名字,是 init callback 方法所在 module 的名字;
  • 第二个参数 init callback 方法的参数列表;
supervisor 的执行流程如下:
 

supervisor:start_link  --> init --> 根据指定的子规范的入口来启动它的所有子进程
 


注意
 
supervisor:start_link 是同步的,当所有子进程启动之后才会返回
 
 


【动态添加子进程】

1
supervisor:start_child(Sup, ChildSpec)
Sup 是 supervisor 的 pid 或名字,ChildSpec 是子进程规范;
 

使用 supervisor:start_child/2 添加的子进程会表现出像其他子进程一样的行为,除了这点,如果 supervisor 死掉然后重启,则所有动态添加的子进程都将丢失
 


【停止一个子进程】

任何子进程,不管静态的还是动态的,都可以使用 shutdown 规范来停止。
 

1
supervisor:terminate_child(Sup, Id)
停止的子进程的子规范使用如下调用来删除。
 

1
supervisor:delete_child(Sup, Id)
Sup 是 supervisor 的 pid 或 name,Id 是子规范里指定的 id 。
 

就像动态添加的子进程一样,如果 supervisor 本身重启,那么删除静态子进程的效果会丢失
 


【simple_one_for_one】

采用 simple_one_for_one 重启策略的 supervisor 是一个简化的 one_for_one supervisor,所有的子进程都是动态添加的同一类型子进程的实例。
 

1
2
3
4
5
6
7
8
9
10
11
12
13
-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 通过 supervisor:start_link/2 启动后,将不会启动任何子进程,而是通过调用如下代码来动态添加子进程:
 

1
supervisor:start_child(Sup, List)
Sup 是 supervisor 的 pid 或 name,List 是一个任意的 term 列表,该列表值将会被动态添加到子规范的参数列表里;
 

如果启动方法指定为 {M, F, A},则子进程的启动是通过调用 apply(M, F, A++List) 来完成的。 
 


【supervisor 的终止】

既然 supervisor 是 supervision tree 的一部分,则其将自动被它自身的 supervisor 所终止;当终止时,它会按启动的反顺序根据相应的 shutdown 规范来自动终止它所有的子进程,然后终止本身。
 

转载地址:http://jvqoo.baihongyu.com/

你可能感兴趣的文章
解决win7的outlook打不开的问题
查看>>
Redis配置文件参数说明
查看>>
TSQL 根据表名生成UPDATE SELECT INSERT
查看>>
Java第五次作业--面向对象高级特性(抽象类和接口)
查看>>
Linux进程间通信(四) - 共享内存
查看>>
事件处理
查看>>
安卓自定义View进阶-分类与流程
查看>>
android 学习随笔十六(广播 )
查看>>
WorldWind Java 版学习:1、启动过程
查看>>
cep
查看>>
postgresql安装配置
查看>>
softlayer virtual machine vhd磁盘镜像导入shell脚本
查看>>
python cookbook 笔记三
查看>>
小程序 公众号/h5相互跳转-webview
查看>>
AaronYang WCF教程目录
查看>>
Python 3.5.2 TypeError: a bytes-like object is required, not 'str’问题解决方案
查看>>
Android中SimpleAdapter的使用—自定义列表
查看>>
Java常见Jar包的用途
查看>>
P1616 疯狂的采药(洛谷,动态规划递推,完全背包)
查看>>
DAL调用SP时出现的异常处理
查看>>