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





.net defensive-programming (6)


它适用于所有地方 。 无论您是否以“让它崩溃”模式编写软件,它都会崩溃,例如,当硬件出现故障时。 “让它崩溃”适用于您需要承受现实的任何地方。 詹姆斯汉密尔顿:

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

但这并不意味着“永远不会使用警卫”。 但是不要害怕崩溃!

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

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

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




我的同事和我自己都认为这个主题不是特别技术明智,而是从域名角度和安全角度来看。

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

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

我个人认为它在许多情况下都适用,甚至是可取的,特别是当有很多错误处理时(安全相关系统)。 你不能总是使用Erlang(缺少实时功能,没有真正的嵌入式支持,客户端发送......),但我很确定你可以实现它(例如使用线程,异常,消息传递)。 我还没试过,但是我想。




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

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

在某人无法快速对失败采取行动的情况下,让失败停止系统或吞下失败并尝试继续前进是否更为有益。




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

有了这个说我认为Erlang必须是一个特殊情况,你不仅可以立即重启,重新启动的程序可以弹出,环顾四周并说“啊......那就是我在做什么!”




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

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

你得到了一个悖论,你在哪里思考各地的错误和失败,目的是在尽可能少的地方实际处理它们。

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

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




对于任何对asp.net网络应用感兴趣的人。 这是我3种不同方法的结果

protected void Application_Start(object sender, EventArgs e)
{
  string p1 = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
  string p2 = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
  string p3 = this.Server.MapPath("");
  Console.WriteLine("p1 = " + p1);
  Console.WriteLine("p2 = " + p2);
  Console.WriteLine("p3 = " + p3);
}

结果

p1 = C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\a897dd66\ec73ff95\assembly\dl3\ff65202d\29daade3_5e84cc01
p2 = C:\inetpub\SBSPortal_staging\
p3 = C:\inetpub\SBSPortal_staging

该应用程序在物理上从“C:\ inetpub \ SBSPortal_staging”运行,因此第一个解决方案绝对不适合Web应用程序。





java .net erlang defensive-programming