为啥有一个监督树而不是一个集中的监督者?

Posted

技术标签:

【中文标题】为啥有一个监督树而不是一个集中的监督者?【英文标题】:Why have a supervision tree instead just one centralised supervisor?为什么有一个监督树而不是一个集中的监督者? 【发布时间】:2020-12-02 20:15:07 【问题描述】:

我正在学习 Elixir 和 Erlang/OTP,想了解监督树在构建高可用性系统中的重要性。

我可以看到主管在管理工作进程生命周期中的重要性。但是,我还是想知道为什么有些应用程序需要以层次结构的形式组织主管,而不是只有一个主管来管理所有的工作人员?拥有我天真地忽略的这种结构有什么实际好处吗?

借用Programming Elixir书中的一个例子,在哪种情况下我们更喜欢第一种结构而不是第二种结构?

1.  MainSupervisor
    ├── StashWorker
    └── SubSupervisor
        └──SequenceWorker

2.  MainSupervisor
    ├── StashWorker
    └── SequenceWorker

【问题讨论】:

【参考方案1】:

您可能忽略的是著名的“让它崩溃”哲学,它使进程崩溃并重新启动 OTP 中的一等公民。我们不会将进程崩溃视为失败,而是将其视为正确重做它而无需手动处理错误的机会。

主要原因是允许对失败时应该重新启动的内容进行更细粒度的控制。为此,我们有strategies。或者,正如@Andree 在 cmets 中重申的那样:

通过在层次结构中组织监督,我们可以更细粒度地控制系统在系统子集出现故障时应如何响应

想象一下,有一个进程负责远程连接的应用程序和一堆进程都使用这个资源。当连接进程崩溃时,无论如何,它都会被其主管重新启动,但它的pid 会发生变化。这意味着依赖此pid 的所有进程也应该重新启动。使用:rest_for_one 策略很容易开箱即用。

此特定示例的另一种方法是管理进程中的连接,在树的另一部分进行监督,并在连接问题时使用此连接手动使池的监督者崩溃以重新初始化所有其中。

更重要的是,我们可能希望手动使处理此连接的进程崩溃以重新初始化它,而不是编写像 if no_conn, do: reload_config_and_restart_connection 这样的防御性代码,我们只是让它崩溃并由监督树使用新的正确配置重新初始化。

最后但并非最不重要的一点是,如果主管不捕获出口,它也会崩溃,并向上传播。这样我们就可以重新初始化监督树的整个分支,而无需编写任何代码。

【讨论】:

感谢您提供的信息丰富的回答。我想你回答了我的问题。如果我可以尝试简洁地说,通过在层次结构中组织监督,我们可以更细粒度地控制系统在系统子集发生故障时应如何响应。 是的,没错,我要用这个措辞修改我的答案。

以上是关于为啥有一个监督树而不是一个集中的监督者?的主要内容,如果未能解决你的问题,请参考以下文章

深度学习之无监督训练

从监督学习数据集中删除列时出现奇怪的值

11.分类与监督学习,朴素贝叶斯分类算法

11.分类与监督学习,朴素贝叶斯分类算法

GAN实战:半监督生成对抗网络

从监督学习数据集中删除列时的奇怪值