Erlang 主管有一个关键的孩子

Posted

技术标签:

【中文标题】Erlang 主管有一个关键的孩子【英文标题】:Erlang supervisor with one critical child 【发布时间】:2014-06-17 03:14:13 【问题描述】:

我们正在重新组织我们的应用程序监督树,以使其更稳健地处理故障和重新启动。但是,我们有一个场景,我们有一个父主管启动四个子主管。我们遇到的问题是,第一个子主管启动了几个子 gen_server,这些子 gen_servers 必须在第二个子主管启动之前启动和初始化,否则它将失败。

所以,我需要一个像下面这样的创业公司:

test_app.erl -> super_supervisor -> [config_supervisor, auth_supervisor, rest_supervisor]

我遇到的问题是 config_supervisor 必须在 auth_supervisor 或 rest_supervisor 启动之前完成所有初始化。使用 rest_for_one 启动策略,我基本上得到了这种行为,但只能通过允许 auth_supervisor 失败,因为所需的配置不存在。我宁愿只要求 config_supervisor 完成初始化(包括启动几个 gen_servers),然后再转到 auth_supervisor。

这似乎是以前可以克服的常见情况,但是我很难“谷歌搜索”解决方案。是否有人有可能存在的建议或示例代码来处理这种情况?

【问题讨论】:

【参考方案1】:

Supervisors 会同步启动他们的孩子,依次启动每个孩子,然后再启动下一个 按照它们在 childspeclist 中出现的顺序。所以你的super_supervisor 应该以正确的顺序开始它的孩子,首先是config_supervisor,然后是auth_supervisor,最后是rest_supervisor,按顺序排列它们。主管必须(成功地)启动其所有子项,然后才能被视为启动。因此,如果 config_supervisor 具有所有必须在初始化期间作为其子级启动的必要进程,那么 super_supervisor 将在 config_supervisor 完成之前不会启动其他主管。

在这种情况下,如果孩子在 childspeclist 中的顺序正确,则您不需要rest_for_one 来确保以正确的顺序开始。

对于工作进程 gen_server/gen_fsm/gen_event,它们在其 init 回调返回时被视为已启动。

我是否正确理解了您的描述和问题?

【讨论】:

【参考方案2】:

您可以尝试将 config_supervisor 移动到它自己的应用程序中,并将应用程序设置为主应用程序的要求,在这种情况下,配置应用程序将首先启动,然后具有 auth_supervisor 等的主主管将开始初始化。

【讨论】:

【参考方案3】:

你看rest_for_one重启策略了吗?在这种情况下似乎应该很方便,中间主管按定义的顺序启动 gen_servers,最后是叶主管,叶子主管依次启动关键进程。

【讨论】:

这是错误的顺序。 rest_for_one 将杀死关键进程,如果任何 gen_server 实例死亡。通常,关键进程应该靠近树的顶部。 好吧,当我读到这个问题时,这是我所理解的,除非 4 个 gen_servers 启动,否则此过程无法运行。我的“关键过程”措辞似乎不恰当 谢谢@Pascal。这很接近,但我想我可能没有正确描述这个场景。我会更新问题。 我阅读了您的编辑,在这种情况下,我认为您可以使用与我建议的主管相同的层次结构,但使用 one_for_one 重新启动策略。您保持进程启动的顺序,但如果一个 gen_server 死亡,请避免杀死关键的进程。事实上,还不够清楚的是您在失败时需要的重启顺序。

以上是关于Erlang 主管有一个关键的孩子的主要内容,如果未能解决你的问题,请参考以下文章

如何将孩子添加到 erlang 主管?

Erlang simple_one_for_one 主管不重启孩子

我怎么知道这是由 erlang 中的主管重新启动我的进程的最后一个周期

在erlang中注册全局主管和本地主管有啥区别

如何分发 Erlang 进程(主管行为)?

重新启动 => erlang 主管的瞬态与永久