erlang - 为什么有一个监督树而不是一个集中的监督者?
问题描述
我正在学习 Elixir 和 Erlang/OTP,并想了解监督树在构建高可用性系统中的重要性。
我可以看到主管在管理工作进程生命周期中的重要性。但是,我还是想知道为什么有些应用程序需要以层次结构的形式组织主管,而不是只有一个主管来管理所有的工作人员?拥有我天真地忽略的这种结构有什么实际好处吗?
借用Programming Elixir书中的一个例子,在哪种情况下我们更喜欢第一种结构而不是第二种结构?
1. MainSupervisor
├── StashWorker
└── SubSupervisor
└──SequenceWorker
2. MainSupervisor
├── StashWorker
└── SequenceWorker
解决方案
你可能忽略的是著名的“让它崩溃”哲学,它使进程崩溃并重新启动 OTP 中的一等公民。我们不会将进程崩溃视为失败,而是将其视为正确重做它而无需手动处理错误的机会。
主要原因是允许对失败时应该重新启动的内容进行更细粒度的控制。为此,我们有strategies
. 或者,正如@Andree 在评论中重申的那样:
通过在层次结构中组织监督,我们可以更细粒度地控制系统在系统子集发生故障时应如何响应
想象一下应用程序有一个负责远程连接的进程和一堆进程,它们都使用这个资源。当连接进程崩溃时,无论如何,它都会被其主管重新启动,但它pid
会发生变化。这意味着所有依赖于此的进程也pid
应该重新启动。有了:rest_for_one
策略,就很容易开箱即用。
此特定示例的另一种方法是管理进程中的连接,在树的另一部分进行监督,并在连接问题时手动使池的监督者使用此连接重新初始化所有池。
更重要的是,我们可能希望手动使处理此连接的进程崩溃以重新初始化它,而不是编写防御性代码,就像if no_conn, do: reload_config_and_restart_connection
我们让它崩溃并由监督树使用新的正确配置重新初始化一样。
最后但并非最不重要的一点是,如果主管不捕获出口,它也会崩溃,并向上传播。这样我们就可以重新初始化监督树的整个分支,而无需编写任何代码。
推荐阅读
- arrays - 如何使用 *ngFor 指令在 angular6 中访问从 ts 到 html 的 json 数组
- github - 如何将图像移动到 GitHub 文件夹
- batch-file - 如何使用批处理文件使用 Windows 命令处理器进行平方根?
- python - 如何从 python 中的 pandas 数据框中创建的系列中检索值
- php - 如何将数据URI转换为文件并将其保存到目录
- arrays - iOS Swift如何从另一个数组中的部分字符串中删除数组中的字符串
- r - 关于在r中计算样本相关性的困惑
- python - 迭代从 excel 文件列创建的 pandas 数据框时出错
- php - 如果价格在 Woocommerce 3 中更新,则更改产品状态
- python - 如何测试 Django CreateView 和 form_valid