达到_max_restart_intensity 的主管如何只删除违规的孩子?
Posted
技术标签:
【中文标题】达到_max_restart_intensity 的主管如何只删除违规的孩子?【英文标题】:How can a supervisor that reached_max_restart_intensity only delete the offending child? 【发布时间】:2011-07-26 00:54:21 【问题描述】:我有一个 one_for_one
主管,负责处理相似且完全独立的孩子。
当一个孩子出现问题时,反复崩溃触发:
=SUPERVISOR REPORT==== 30-Mar-2011::13:10:42 ===
Supervisor: local,gateway_sup
Context: shutdown
Reason: reached_max_restart_intensity
Offender: [pid,<0.76.0>, ...
自行关闭并终止所有无辜的孩子,否则这些孩子会继续正常运行。
如何从标准 Erlang 监督者构建监督树,只停止重新启动一个有问题的孩子而让其他孩子独自一人?
我正在考虑增加一个只带一个孩子的主管,但这对我来说似乎很重要。
还有其他方法可以处理吗?
【问题讨论】:
额外的主管只会把问题推得更深。它仍然会崩溃,然后崩溃***主管。在这种情况下,只需增加最大重启次数和最大时间值... @Adam:我需要停止重新启动孩子,因为它似乎阻止了我与主管交谈。所以我真的希望它停止重新启动有问题的孩子,但不终止其余的孩子。我希望无需编写自己的主管就可以实现这一点。 如果我错了,请纠正我,但我将您的场景总结为:您有一个具有完全独立孩子的主管,孩子可以在启动时超时或在运行时崩溃,您想重新启动每个孩子在不影响其他孩子的情况下停止重新启动行为不端的孩子? 感觉你搞错了。 Adam 的解决方案巧妙地解决了问题,但感觉您需要看看为什么会崩溃,而不是崩溃并等待人工干预。如果您的主管因为忙于尝试重新启动立即崩溃的东西而被锁定,那么您就崩溃了。 (是的,存在崩溃错误之类的事情;)我建议您查看您的恢复策略,即您如何从崩溃中重新启动以及哪些错误数据可能会将其锁定在一个紧密的循环中。 @Mazen:你的感觉是对的:我错了,我要改变它。 但是我利用这个机会使整个监督的东西更加健壮,以防止“错误崩溃”。麻烦的是,虽然我可以改进常见情况,但我开始使用的代码具有相当复杂的启动,即使一个孩子的行为出乎意料地非常讨厌(无故终止孩子会产生大量金钱),其他孩子继续运行是非常重要的在这里给客户造成损失,甚至可能发生硬件损坏) 【参考方案1】:我认为最好的解决方案是有两层监督。
一个主管为您要运行的每个 gen_server
启动一个主管 + 进程对。此主管配置了one_for_one
策略和temporary
子级。
在此主管下运行的每个主管都会正确配置 MaxR
和 MaxT
值,一旦孩子行为不端,这将触发该主管崩溃。
当较低级别的主管崩溃时,***主管“根本不在乎”。
一个监督者从一个孩子开始时消耗 233 个字节(总堆大小),因此内存消耗应该不是问题。
监督树应如下所示:
supervisor_top
|
|
+------------------------+----- ...
| |
supervisor_1 supervisor_2
restart temporary restart temporary
| |
gen_server_1 gen_server_2
restart transient restart transient
【讨论】:
据我所知,我在您的答案中添加了一个图表。这是你的意思吗? 谢谢!顺便说一句,此设置还避免了通过重启循环 (***.com/questions/5485402/…) 阻塞主管的问题,因为 supervisor_top 被可能的重启循环隔离,这些重启不会触发中间主管的速率限制。以上是关于达到_max_restart_intensity 的主管如何只删除违规的孩子?的主要内容,如果未能解决你的问题,请参考以下文章