Erlang 主管进程

Posted

技术标签:

【中文标题】Erlang 主管进程【英文标题】:Erlang supervisor processes 【发布时间】:2014-11-29 03:52:38 【问题描述】:

我一直在深入学习 Erlang,在完成了 Joe Armstrong 的“Programming Erlang”之后,我一直在回顾一件事。

在我看来,主管为每个子处理程序生成一个进程。因此,每个声明的 gen_server 类型处理程序都将作为一个单独的进程运行。

如果您正在构建一个小型 Web 服务器并且希望每个请求都成为自己的进程,会发生什么情况。您是否仍然遵守 OTP 原则并以某种方式使用 gen_server(如何?),还是创建自己的行为?

例如,Cowboy 如何处理这个问题。 ?它仍然使用 gen_server 吗?

【问题讨论】:

【参考方案1】:

tl;dr:我发现在项目开始时试图找出“正确”的监督结构是过早优化的一种形式。

设计监督树的“正确”方式取决于应用程序的工作部分在做什么。对于 Web 服务器,我可能会首先探索以下内容:

最高主管(单数) 数据服务主管(每种服务类型一个) 工作人员池(服务支持下的所有工作人员) 客户端连接主管(一) 连接工作器池(或每个连接一个,必须使用它来决定) 逻辑主管(视情况而定——此处存在巨大差异,取决于问题域) 工作人员或主管(视情况而定 - 必须探索/了解问题领域才能知道应该如何构建)

因此,在较低级别,每个主管类型有几个工人。我没有使用过 Cowboy,所以我不知道它是如何组织的。我要说明的一点是,虽然处理为网页提供服务的数据服务的机制相对微不足道,但实际执行核心问题解决工作的系统部分可能并不重要,这将决定所有有趣的事情系统。

将您的问题解决位与您的网络显示或连接处理位混合在同一个模块中是一件坏事。理想情况下,您应该能够在本机应用程序、Web 应用程序和网络服务中使用相同的逻辑单元,而无需进行任何更改。

最终,您是否应该有 1:1 的主管与工人或 1:n 的答案取决于您正在做什么以及哪种重启策略可以让您在恢复到已知的一致状态、用户感受到的延迟之间取得最佳平衡,以及资源使用情况。

我最喜欢 Erlang 的一件事是,我可以从上面那种幼稚的主管结构开始,玩弄它直到我发现它哪里不太好,然后轻松地切换并尝试替代方案,而无需从根本上改变我的系统很多。 (如果您围绕它们编写适当的抽象,则使用替代数据表示也是如此。)因此,首先,获得在测试中有效的东西。然后加载它,看看你是否可以打破它。然后开始担心细节,你明白问题出在哪里之后。

【讨论】:

感谢您提供详细且非常有用的答案。静态监督与动态监督确实是我遇到的问题,因为 Joe Armstrong 的“Erlang 编程”没有涉及动态监督。 @Pascal 的答案正是我想要的,但我将这个绿色标记为深度。 确实,Joe 的书比 OTP 更深入地探讨了 Erlang 作为一种语言和运行时。 LYSE 为 OTP 概念(如监督树和重启策略)提供了更多时间。请记住,无论您做什么,监督都是要返回到已知状态(本质上是逻辑分类),无论每个监督员管理多少进程。这是一种不同的思维方式,需要一段时间才能真正沉浸其中(你可能会有一个“啊哈!”的时刻)。【参考方案2】:

在 erlang 中为每个客户端生成一个服务器是一种常见的模式,然后您将使用一个使用 simple_one_to_one 策略的子服务器的主管。这允许要求服务器按需启动服务器。通常,当您不知道需要多少进程以及进程是独立的(一个进程的崩溃不应影响另一个进程)时,会使用此选项。

在learningyousomeerlang.com(LYSE supervisor chapter)这个网站上有一个很好的信息。整个网站都值得一读。

【讨论】:

“LYSE”中的动态监督正是我想要的。非常感谢。

以上是关于Erlang 主管进程的主要内容,如果未能解决你的问题,请参考以下文章

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

Erlang:supervisor(3),添加子进程

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

OTP 主管可以监控远程节点上的进程吗?

Erlang 主管有一个关键的孩子

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