首页 > 代码库 > Supervisor

Supervisor

一、概念:
  Supervisor: 监控树

二、作用:
  用于监控其它的进程是否正常运行

三、定义监控树的行为和被监控的进程:

  1. 整个监控树的重启策略:(如果一个进程停止了,如何处理)
    1. one_for_one : 如果一个子进程停止了,则中重启访进程
    2. one_for_all   : 如果一个子进程停止,所有其他子进程也停止,然后所有进程重启
    3. rest_for_one : 如果一个子进程停止,则启动顺序中在它之后的所有其他子进程也停止, 然后重启停止进程
    4. simple_one_for_one:
             1. 一个简化的one_for_one
      2. 运行相同的代码,即只有一类子进程
      3. 监控树启动后,不启动子进程
      4. 动态添加

  2. 重启频率:在一定的时间内(MaxT)(秒),重启的次数超过了最大的重启次数(MaxR),监控树就会关闭所有的子进程和其本身
  3. 子进程的定义:
    1. Id : 一个标记,自定义,来区分不同的进程
    2. StartFunc : {Mod, Fun, Args}
    3. Restart :
      1. permanent: 子进程总是重启
      2. transient: 子进程只会在非正常结束时,才会重启
      3. temporary: 绝对不重启,即除normal, shutdown, {shutdown,Term}之外的原因
  4. Shutdonw:
    1. brutal_kill : 无条件终止,使用exit(Child, kill)
    2. 一个时间(非负): 先使用exit(Child, shutdown),等待一段时间,如果没有返回的shutdown, 就使用exit(Child, kill),强制杀死进程
    3. infinity : 一直等待,当子进程也是一个监控树的时候强烈推荐这个,使子树有足够的时间结束
  5. Type:
    1. supervisor : 表明此进程也是一个监控树
    2. worker : 表示此进程是一个工作进程,即用来执行具体操作的进程
  6. Modules:
    1. 假如子进程是supervisor、gen_server 或 gen_fsm,那么Module,就是一个列表,里面仅仅包含一个模块的名称,eg: [ModeName];
    2. 假如子进程是gen_event,那么Modules应该是dynamic

四、一个supervisor模版的构成:

  1. start_link函数:用于创建监控树本身,这个函数中,仅仅调用 supervisor:start_link:
    1. start_link的参数(三个)
      1. 给监控树起一个名字,分为三种,local,global,via
        1. {local, SupName}    : 注册一个本地的名字
        2. {global, SupName}  : 注册一个全局的名字,跨节点
        3. {via, Module, Name}:
      2. 监控树所在的模块
      3. 需要传给Module:init的函数,如果是多个参数的话,就用列表
    2. 返回值:
      1. {ok, pid()}     : 成功
      2. ignore            : 如果Module:init函数返回ignore,就返回ignore
      3. {error, Why}  : 失败
    3. start_link,会调用Module:init的函数去找到重启策略与所有的子进程,start_link会在Modult:init初始化结束后,并且所有子进程都已经启动后,才会返回

  2. init函数:返回对监控树的定义和被监控的子进程,类似{ok, {{重启策略,MaxR, MaxT}, [AllChildProcess]}}的结构
    1. {重启策略,MaxR, MaxT}, 重启策略和最大重启频率
    2. [AllChildProcess], 定义被监控的子进程

Supervisor