gpt4 book ai didi

erlang - 自动重启动态添加的主 pipe 级

转载 作者:行者123 更新时间:2023-12-03 23:15:30 26 4
gpt4 key购买 nike

根据Erlang / OTP手册,如果我使用supervisor:start_child将一个孩子添加到主管中,而该主管崩溃了,该孩子将不会自动重新启动。

http://www.erlang.org/doc/design_principles/sup_princ.html#id73986

是否有一个简单的解决方法,还是我必须以某种方式手动保存动态添加的子代并自行管理重启? (我的主管在上面有一个主管,所以这是可能的,尽管不是很优雅。)

最佳答案

您的主管是与其他任何人一样的流程,不同之处在于他们是系统流程(所有trap_exit业务)。当它死亡时,它所持有的内部状态随之而来-of!

这是一件好事

主管死亡的恢复与工人死亡的恢复相同(毕竟,主管是另一位主管的工人)。您可能遇到的情况是,监督树的结构与您的需求不太吻合。如果您需要工作以使他们的主管去世,那么这些任务比您放置的任务更接近程序的崩溃核心-这意味着它们应该是更高层次的东西的子代,或者(更可能是),您高估了它们对系统的重要性。

我开始担心确保流程持续存在的最常见原因是当我赋予它过多的责任时。每当我发现自己问诸如“如果上司崩溃时如何确保上司重启孩子的问题”之类的问题时,我就会停下来几分钟,仔细考虑为什么要问这个问题-这总是使我发现一个架构问题(修复它总是使系统其余部分的其他事情变得更加明智)。

现实生活中的例子:

在业务服务器中,存在一个过程模块,该过程模块最初是“仅客户机连接”。它成长为管理到客户端的网络连接,内部Erlang值和外部协议值之间的转换,以及代表系统中客户端的存在(状态,审核活动,授权,聊天等)。由于审核日志记录,我开始想知道与您相同的事情:如果成功,我如何关闭客户接触的事物,等等?

然后发生了一件显而易见的令人讨厌的事情,那就是:必须同时从多个设备登录。当有多个“客户端”等时,多设备登录很奇怪(依此类推)(而不是单个客户端进程仅使用多个连接进程)。将这些任务分为不同的流程(而不仅仅是模块)大大简化了事情,并使状态恢复结构更加明显和清晰。

附录

OP问:“为什么静态和动态子项在这方面有区别呢?”好问题。为什么我们有静态的子定义,动态的监督命令(如supervisor:start_child/2supervisor:delete_child/2以及那些奇怪的simple_one_for_one监督者)?

关键在于您的用例。假设我有一个游戏服务器,需要始终有一个大厅,以便玩家可以登录,聊天,查看军械库网站,在论坛上贴上菜鸟问题和反开发者的言论,并且通常以其他方式浪费时间与实际游戏有关。我们从不希望发生崩溃而立即将它们全部关闭,但是也许我们确实希望能够告诉不同的运行服务在网络上侦听或停止接受按需的连接。但是,实际的游戏领域存在于监管树各自的分支中-如果其中一个崩溃,我们不希望它带走其他一切,当然我们也不想失去整个集群。

那么我们将如何构建呢?所有基本服务都将直接写入主管树子定义中-除非我们手动造成,否则那里没有动态性。每当我们启动系统时,它们就会弹出。但是,由于我们可能拥有任意多个游戏领域,而领域定义在内部构造为大多数静态定义的监督树,因此,每个领域级别的主管都是管理所有领域的simple_one_for_one主管的子代(因此,如果该主管崩溃,则POOF!每个人都回到大厅,可能很生气。可以根据我们的命令,设置文件或db数据或它们的组合来启动领域。

但是,延迟外部网络服务的启动可能是一件好事。初始化系统时,我们可能会执行一些重要的启动任务,并且无论如何,都可能必须在集群中的不同节点上启动侦听器。为了避免直接通过网络连接给系统施加压力,请给我们时间检查系统或运行测试,并有机会将系统设置为我们希望的某些特定模式(基准测试,测试,锦标赛或其他)延迟外部网络服务的启动。也就是说,我们迫使系统等待命令发送,然后再向未清洗的群众打开狂欢之门。我们将把命令包装成一些简单的调用,可以从外壳或网络(如waste_of_youth:tempt_souls(Node, Port, Cert))访问,但是这样做会导致一系列supervisor:start_child/2调用-并且这些调用是动态的。

那么,如果网络服务经理去世了怎么办?连接到POOF!在我们告诉他们之前,它们不会再次出现(不仅是活动的连接,而且是侦听器,它们可能独立于活动的连接而死亡,具体取决于崩溃的管理员),因为系统是按照这种方式设计的。但是,如果有问题,我们可以采取许多措施来减轻这种情况。我们可能有一个流程,其工作是了解和监视某些特定服务的最新状态,例如外部网络-如果它发生意外更改,请自行发起呼叫。但这通常不是您想要的-在大多数情况下,当您需要自动重新启动服务时,您希望在启动时将永久性服务的静态定义读入系统。

上面我提到了不同的模式,我们可能希望在启动时将服务器放入。将子代定义与其余代码分开是很方便的,因此当我告诉它“以游戏测试模式启动”时,它会加载一些不同的主管定义(除非我们弄乱它,否则它将坚持下去)。如果我告诉它“从生产模式开始”,也许我们会加载包含静态定义的永久网络服务处理程序的子定义。每种情况下的一组主管定义-这样,您可以轻松创建服务配置文件。这些动态主管命令使您可以在服务状态之间手动切换,或将该切换过程委托给您在代码中定义的命令。

关于erlang - 自动重启动态添加的主 pipe 级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34631333/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com