【问题标题】:Erlang supervisor with one critical childErlang 主管有一个关键的孩子
【发布时间】: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。

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

【问题讨论】:

    标签: functional-programming erlang erlang-otp erlang-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 死亡,请避免杀死关键的进程。事实上,还不够清楚的是您在失败时需要的重启顺序。
        猜你喜欢
        • 2012-06-22
        • 2017-05-02
        • 2017-05-02
        • 2012-11-11
        • 2017-09-20
        • 2015-06-02
        • 2018-09-10
        • 1970-01-01
        • 2016-06-11
        相关资源
        最近更新 更多