【问题标题】:difference between worker and supervisor elixir apps工人和主管灵丹妙药应用程序之间的区别
【发布时间】:2018-03-22 05:41:26
【问题描述】:

我对长生不老药/凤凰很陌生。我正在开发一个以前创建的具有多个存储库的应用程序,今天我看到一个示例,让我想知道该配置意味着什么

我想我不知道如何搜索这就是我在文档中找不到正确答案的原因

首先我正在使用的应用程序有类似

defmodule RestApi do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      supervisor(RestApi.Endpoint, []),
      supervisor(RestApi.Repo, []),]),
      supervisor(RestApi.OtherRepo, []),]),
    ]

    opts = [strategy: :one_for_one, name: RestApi.Supervisor]
    Supervisor.start_link(children, opts)
  end

  def config_change(changed, _new, removed) do
    RestApi.Endpoint.config_change(changed, removed)
    :ok
  end
end

他们使用函数Supervisor.Spec.supervisor/3 来启动/管理一切

后来我找到了一个例子

defmodule RestApi do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false

    children = [
      supervisor(RestApi.Endpoint, []),
      worker(RestApi.Repo, []),
    ]

    opts = [strategy: :one_for_one, name: RestApi.Supervisor]
    Supervisor.start_link(children, opts)
  end

  def config_change(changed, _new, removed) do
    RestApi.Endpoint.config_change(changed, removed)
    :ok
  end
end

example 中,他们使用Supervisor.Spec.worker/3 来启动/管理回购

这有什么区别?我的意思是如何影响应用程序(性能、内存消耗等)

【问题讨论】:

标签: elixir phoenix-framework


【解决方案1】:

把supervisor想象成监督树的一个分支,而worker是一片叶子。

每个supervisor 都是worker,而不是每个worker 都是supervisor。尽管supervisor 有一堆专门用于管理子进程的函数,但与通用gen_server 相比,它实际上对生产力的影响非常小。 OTP design principles 的这段摘录解释了 supervisor 的用途:

主管负责启动、停止和监视其子进程。监督者的基本思想是通过在必要时重新启动子进程来保持其子进程的活动。
要启动和监视哪些子进程由子规范列表指定。子进程按此列表指定的顺序启动,并以相反的顺序终止。

除此之外,它是“worker”。

也就是说,有一条很容易采用的经验法则:当进程管理子进程时,它是supervisor,否则它是worker

在提到的例子中:

children = [
  supervisor(RestApi.Endpoint, []),
  worker(RestApi.Repo, []),
]

RestApi.Endpoint 管理子进程,RestApi.Repo 不管理。除此之外,两者都是普通的老好gen_servers。

【讨论】:

  • 如果我可以问你最后的声明;规定RestApi.Repo 没有子进程这一事实的规则是什么?
【解决方案2】:

您使用supervisor 启动作为主管的进程,并使用worker 启动工作人员(基本上任何不是主管的进程)。您可以在 Supervisor 和 Supervisor.Spec 模块文档中找到更多相关信息。

似乎进程类型在版本之间发生了变化,或者其中一个示例有错误,但我相信它应该是一个工作进程,但我会查看 Ecto 文档。

至于它如何影响应用程序,除了子进程类型的文档之外没有任何有意义的区别——它实际上在 Erlang 中是可选的。监督者管理他们自己的一组子进程,形成监督者树。您可以使用它来隔离崩溃对该树的子分支的影响,以便应用程序的不相关部分可以在故障分支由其主管重新启动时继续运行。这是语言中容错的来源,也是 OTP 的基本构建块。

Worker 是迄今为止最常见的进程类型,它们不管理子进程,并且设计为在出现问题时崩溃并由其主管重新启动,其想法是从一个干净、已知的状态重新开始。太多失败会导致父主管崩溃,而父主管又会由其主管重新启动 - 如果这冒泡到应用程序的顶级主管,则应用程序将崩溃。

希望对您有所帮助:)

【讨论】:

    猜你喜欢
    • 2018-06-12
    • 2019-02-15
    • 1970-01-01
    • 2018-10-11
    • 2019-11-30
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多