68

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

我想知道的是——这种方法是否只适用于像 Erlang 这样的平台?Erlang 有一个虚拟机,它对进程监督树具有简单的原生支持,并且重新启动进程非常快。我是否应该将我的开发工作(不在 Erlang 世界中时)花在重新创建监督树上,而不是让自己陷入顶级异常处理程序、错误代码、空结果等等等。

你认为这种方法的改变在(比如说).NET 或 Java 领域会很好用吗?

4

7 回答 7

37

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

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

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

于 2010-12-08T23:01:45.693 回答
27

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

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

你会发现到处都在考虑错误和失败的悖论,目的是在尽可能少的地方实际处理它们。

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

您确实需要一种在出现问题时生成错误/异常的语言,以便您可以捕获它们或让它们使进程崩溃。只是忽略错误返回值不是一回事。

于 2010-12-09T22:29:12.110 回答
5

它被称为快速失败。这是一个很好的范例,前提是您有一个可以对失败做出反应(并且反应迅速)的团队。

在海军中,所有管道和电气设备都安装在墙的外部(最好是墙的更公共的一侧)。这样,如果存在泄漏或问题,则更有可能快速检测到。在海军中,人们因不响应故障而受到惩罚,因此它运作良好:故障被迅速发现并迅速采取行动。

在某人无法迅速对故障采取行动的情况下,让故障停止系统或吞下故障并尝试继续前进是否更有利,这将成为一个见仁见智的问题。

于 2010-12-08T23:02:22.520 回答
5

我编写的程序依赖于来自现实世界情况的数据,如果它们崩溃,可能会造成巨大的物理损失(更不用说巨大的收入损失)。如果我不进行防御性编程,我很快就会失业。

话虽如此,我认为 Erlang 一定是一个特例,它不仅可以立即重新启动,还可以弹出一个重新启动的程序,环顾四周说“啊……那是我正在做的!”

于 2010-12-08T23:03:00.623 回答
5

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

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

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

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

于 2013-09-14T12:10:30.913 回答
3

恕我直言,一些开发人员使用几乎没有价值的代码处理/包装检查的异常。除非您要处理它并添加一些价值,否则允许方法抛出原始异常通常更简单。

于 2010-12-08T23:02:32.027 回答
1

是的,即使在经济领域,请参阅这篇文章:https ://www.nytimes.com/2020/04/16/upshot/world-economy-restructuring-coronavirus.html 。世界变成了“意大利面条代码”,正在遭受“全球状态”问题。

于 2020-04-16T09:54:22.737 回答