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 simple_one_for_one 主管不重启孩子