[elixir! #0017] Supervisor 究竟怎麼用

初學 Elixir, 我經常對 Supervisor 的概念感到疑惑. 沒有Supervisor, 程序也能正常運行, 爲何還要加上這個東西呢? 原來, 這和 Erlang 的基本信條 —— 「就讓它崩潰」 有關, 在 Erlang 中, 是沒有 try…rescue 這樣的錯誤救援機制的. 取而代之的是 Supervisor 機制, Supervisor 是一個專門用來監督進程的進程, 每當它的名下有進程出錯崩潰, Supervisor就會按照既定的策略重啓進程.網絡

咱們將 Supervisor 名下的進程叫作子進程, 將由 Supervisor 和子進程所組成的監督網絡稱爲 監督樹. 有了監督樹的幫助, 咱們能夠方便地構建一個高容錯的應用.函數

這裏要注意模塊和進程的關係. 模塊是函數的集合, 而相似 start_link 的函數能夠建立進程, rest

那麼, 如何在 phoenix 項目裏使用 Supervisor 呢? ELixir 內置了兩個模塊: Supervisor 和 Supervisor.Spec.code

Supervisor.Spec

咱們能夠這樣設置 supervisor 名下的子進程:orm

import Supervisor.Spec

children = [
  worker(MyWorker, [arg1, arg2, arg3]),
  supervisor(MySupervisor, [arg1])   # 這個 supervisor 也是子進程
]

Supervisor.start_link(children, strategy: :one_for_one)

Supervisor

這是以模塊的方式配置 supervisor, 它包含了 import Supervisor.Spec:進程

defmodule MySupervisor do
  use Supervisor

  def start_link(arg) do
    Supervisor.start_link(__MODULE__, arg)  # 會調用 init 回調
  end

  def init(arg) do
    children = [
      worker(MyWorker, [arg], restart: :temporary)
    ]

    supervise(children, strategy: :simple_one_for_one)
  end
end

‘Supervisor.Spec`的主要函數

supervise(children, options) 會以tuple 的形式返回一個 supervisor配置. it

supervisor(module, args, options \ []) 將給定的模塊設置爲一個 supervisor.io

worker(module, args, options \ []) 將一個給定的模塊定義爲 worker.import

Supervisor 的主要函數

count_children(supervisor)
返回一個清點子進程數的映射.
delete_child(supervisor, child_id)
經過子進程的id 刪除其配置信息.
restart_child(supervisor, child_id)
經過 id 重啓子進程.
start_child(supervisor, child_spec_or_args)
動態添加子進程配置信息, 並啓動它.
start_link(children, options)
按給定的子進程啓動一個 supervisor.
start_link(module, arg, options \ [])
按給定的模塊啓動一個 supervisor .
stop(supervisor, reason \ :normal, timeout \ :infinity)
中止 supervisor.
terminate_child(supervisor, pid_or_child_id)
終止子進程.
which_children(supervisor)
返回子進程列表.module

相關文章
相關標籤/搜索