Erlang的let-it-crash理念 - 适用于其他地方?

And*_*ews 56 .net java erlang defensive-programming

Erlang(或者Joe Armstrong的?)建议不要使用防御性编程并让进程崩溃(而不是用不必要的守卫试图跟踪残骸污染你的代码)对我来说非常有意义,因为我想知道为什么我浪费了这么多多年来一直在努力解决错误!

我想知道的是 - 这种方法只适用于像Erlang这样的平台吗?Erlang有一个VM,它具有对进程监督树的简单本机支持,并且重启进程非常快.我是否应该花费我的开发工作(当不在Erlang世界时)重新创建监督树而不是用顶级异常处理程序,错误代码,空结果等等来掩盖自己.

您是否认为这种方法的改变在(或者说).NET或Java空间中运行良好?

Cra*_*ntz 33

它适用于所有地方.无论您是否以"让它崩溃"模式编写软件,它都会崩溃,例如,当硬件出现故障时."让它崩溃"适用于您需要承受现实的任何地方.Quoth James Hamilton:

如果硬件故障需要立即采取管理措施,则该服务无法经济高效且可靠地进行扩展.整个服务必须能够在没有人工管理交互的情况下幸免于难.故障恢复必须是一个非常简单的路径,并且必须经常测试该路径.斯坦福大学的Armando Fox认为,测试故障路径的最佳方法是永远不要正常关闭服务.只是努力失败.这听起来有点违反直觉,但如果不经常使用故障路径,则在需要时它们将无法工作.

但这并不意味着"永远不会使用警卫".但不要害怕崩溃!

  • 在关键任务系统中,一个常见的解决方案是拥有一个监视主要应用程序的"监视程序"进程.主应用程序旨在快速失败(从而避免程序状态的重新损坏问题),并且监视程序可以重新启动它(或者如果使用热备份设计则故障转移到另一个系统). (2认同)
  • @Andrew:我会说是的.我在.NET和本机Win32代码上使用了fail-fast(我的背景是生产关键自动化编程).Microsoft的Windows错误报告系统专为快速失败的应用程序而设计. (2认同)
  • @Andrew:不在BCL中,但[Windows API代码包](http://code.msdn.microsoft.com/WindowsAPICodePack)包含`ApplicationRestartRecoveryManager.RegisterForApplicationRestart`,如果它在Windows错误中结束,它会自动重启你的应用程序报告(仅适用于Vista及更高版本). (2认同)

rvi*_*ing 25

是的,它适用于所有地方,但重要的是要注意在哪种情况下使用它.它并不意味着该应用程序作为一个整体崩溃,正如@PeterM指出的那样,可以在许多情况下是灾难性的.目标是建立一个整体从不崩溃但可以在内部处理错误的系统.在我们的案例中,电信系统预计每年的停机时间为几分钟.

基本设计是将系统分层并隔离系统的中心部分,以监视和控制执行工作的其他部分.在OTP术语中,我们有主管工人流程.监督员负责监督工人和其他监督员,目的是在工人完成所有实际工作时以正确的方式重新启动工人.使用严格分离功能的原则在层中正确地构建系统允许您将大部分错误处理从工作人员中分离出来进入管理员.你试着用一个小的故障安全错误内核,如果正确可以处理系统其余部分的任何错误.正是在这种背景下,意味着要使用"让它崩溃"的理念.

你会在各处看到错误和失败的悖论,目的是在尽可能少的地方实际处理它们.

处理错误的最佳方法当然取决于错误和系统.有时最好尝试在进程内本地捕获错误并尝试在那里处理错误,如果不起作用,可以选择再次失败.如果您有许多工作进程协作,那么通常最好将它们全部崩溃并重新启动它们.这是一个监督员.

您确实需要一种语言,当出现问题时会生成错误/异常,因此您可以捕获它们或使它们崩溃.只是忽略错误返回值并不是一回事.


Edw*_*uck 5

它被称为失败快速.这是一个很好的范例,只要你有一个能够应对失败的团队(并且快速做到这一点).

在NAVY中,所有管道和电气都安装在墙壁的外部(最好是在墙壁的公共侧面).这样,如果存在泄漏或问题,则更有可能快速检测到.在NAVY中,人们因为没有对故障作出反应而受到惩罚,因此效果很好:快速检测到故障并迅速采取行动.

在这样一个场景,一个人不能在故障迅速采取行动,就成了见仁见智的问题不管是更有利于让故障,杜绝系统或吞下失败和尝试向前继续.

  • 真正的问题:为什么人们把"海军"称为"海军" - 海军不是首字母缩略词? (7认同)
  • 资本化让我一直唱着"在海军中,在海军中"......我该死的. (5认同)
  • 海军显然是处理管道的专家 (4认同)
  • 全部大写NAVY是常见用法,但可能不正确.海军是由NAVSTA(海军基站),NAS(海军航空站)等大量首字母缩略词驱动的.我猜最终海军中的人们已经习惯了所有的大写字母和NAVY类型.除了我的服务时间外,我没有更明确的支持. (3认同)

Pet*_*r M 5

我编写的程序依赖于来自现实世界的数据,如果它们崩溃,它们可能会造成巨大的物理损害(更不用说收入损失的大$$).如果我没有采取防御计划,我就会失业.

随着中说我认为二郎必须是不仅可以重新启动瞬间的事情一个特殊的情况下,重新启动的程序能够流行起来,环顾四周,说"啊..这是我在做什么!"

  • @Peter M:如果您的代码没有副作用,并且您输入相同的输入,那么它将以相同的错误崩溃.Erlang主管具有控制在给定时间段内启动失败进程的次数的参数.如果进程在主管的参数之外崩溃,那么主管将崩溃,并且将通知其主管.但这仍然比你用可变语言得到的更好.Erlang的不同之处在于您仍然可以让进程处理非失败的调用,并且您可以修复错误并对其进行热加载而不会导致系统崩溃. (3认同)
  • @Peter M:我们的目标是建立一个强大的系统,可以在内部处理错误和崩溃但**从来没有**整体下降.在我们的案例中,它是电信系统,预计每年的停机时间为几分钟.基本设计是以这样的方式对系统进行分层,即每个层可以处理下一层中的错误,目标是具有小的错误内核.这意味着系统的大部分不必处理错误,这使得它们更安全并且整个系统更加健壮.正是在这种背景下,使用了"让它崩溃"的理念. (3认同)
  • @Andrew Mathews - 好吧,如果您刷新损坏的状态,并且程序以相同的输入重新启动,那么您是否不会为导致崩溃的相同情况做好准备?还是崩溃被认为是暂时事件,因此不可重复? (2认同)

Chr*_*ski 5

我的同事和我自己不是特别从技术角度考虑这个话题,而是更多地从领域角度和安全重点考虑。

问题是“让它崩溃安全吗?” 或者更好的“是否有可能将像 Erlang 的“让它崩溃”这样的健壮性范式应用到与安全相关的软件项目中?”。

为了找到答案,我们使用具有工业特别是医学背景的接近现实的场景进行了一个小型研究项目。看看这里(http://bit.ly/Z-Blog_let-it-crash)。甚至还有论文可供下载。告诉我你的想法!

我个人认为它适用于许多情况甚至是可取的,尤其是当有很多错误处理要做时(安全相关系统)。你不能总是使用 Erlang(缺少实时功能,没有真正的嵌入式支持,客户希望......),但我很确定你可以以其他方式实现它(例如使用线程、异常、消息传递)。虽然我还没有尝试过,但我很想。