失败快速与稳健

时间:2010-01-28 07:21:26

标签: performance reliability robustness

我们的产品是分布式系统。我工作的模块相当新,非常严格,经过了充分测试。它们是根据最近的最佳实践开发的。其他模块可以视为遗留软件。

虽然我对我负责的模块中发生的所有事情保持警惕,但我仍然面临着处理从其他模块发送给我的错误数据的持续压力。从本质上讲,我是一个“快速失败”原则的开发人员,因此,当问题出现时,我通常能够消除模块中出错的可能性。这不仅仅是责备,只是在错误的地方浪费精力去追逐错误。

但我一直反对的论点是:“我们不能让这些东西在生产中失败,客户希望这个能够发挥作用,为什么你不解决这个问题”。这将是一个强大的论据:你接受的是自由的,你发送的是保守的。

我还应该注意到这些主要是间歇性的问题。我们在集成测试中看到它们,但它们很难重现。涉及时间和并发。

我很难在这两个原则之间取得平衡。部分原因是我担心,如果我开始允许和传播特殊数据,我会引起麻烦,我对系统的信心也不会那么高。但即使其他模块向我发送错误的数据,我也不能反对保持系统正常工作。其他模块没有得到修复的原因是它们太复杂和脆弱,而我的仍然显得清晰和安全。但是,如果我不抵抗压力,我的模块将慢慢地背负着我一直拒绝的同样问题。

我应该说系统没有在生产中“崩溃”,但我的模块可能只是向操作员显示错误并要求他们联系支持人员。崩溃将是一个大问题,但如果我清楚地报告错误,那么这不是正确的做法吗?我怀疑我的同行只是不希望客户看到任何问题,期间。但是我的模块拒绝了我们产品中其他模块的数据,而不是客户输入。所以在我看来,我们只是没有解决问题。

那么,我是否需要更务实或坚持自己的立场?

8 个答案:

答案 0 :(得分:4)

我赞同“快速失败”的偏好/原则。不要将此视为原则冲突,而是更多的理解冲突。您的对手有一些不言而喻的要求(“不要向用户显示不好的时间”),这意味着一些错过的要求。您事先没有机会考虑/实施此要求,因此要求在您的口中留下了不好的味道。忘记这一观点,将其作为一个具有固定要求的新项目重新进行处理。

也许最好的结果是给出一条错误消息,就像你显示的一样。但是,听起来你是在你从对手那里购买之前实施的,当时他们可以选择接受它。关于你在做什么的早期沟通可以解决类似的问题。

小心你如何阻止这些想法。不断提到其他系统“过于复杂和脆弱”可能会以错误的方式摩擦人们。简单地说,系统对您来说是新的,需要更长时间才能理解。花时间去理解它们,这样你就不会降低人们对你能力的期望。

答案 1 :(得分:3)

我会说这取决于你不停止会发生什么。某人的薪水是否被错误处理?订单输出错了吗?那值得停下来。

如果可能的话,拿出蛋糕并吃掉它 - 不要向用户报告错误,让客户同意发送诊断报告并报告每次故障。错误拥有错误模块以修复它们的开发人员。而且我的意思是提出针对他们的bug。或者,如果管理层认为不值得修复成本,请不要。

我还会针对那些失败的模块编写单元测试,特别是如果你能告诉原始输入是什么导致它们产生错误的输出。

真正归结的是,审核您的表现的人希望您,特别是在您通过电子邮件向他们解释问题之后。

答案 2 :(得分:2)

简单地说,这听起来像是“不检查你无法处理的东西”。您正在捕获错误并能够报告它意味着您没有传播它。但这也意味着,既然你可以报告它,你有一些机制可以捕获错误,因此可能自己处理它,并纠正它而不是报告它。

请注意,我假设您的错误报告比您在系统深处捕获的随机异常更有趣。但即便如此,如果你正在测试它并且你正在创建(例如你检查分母是否为零并发送错误而不是简单地无意中除以零并将异常捕获更高),那么这表明你很可能有办法纠正这个问题。

底线,你需要两者。您需要尝试使数据尽可能没有错误,但也要报告意外情况。

我认为你不能锁门并交叉双臂说“这不是我的问题”。它来自“旧的,脆弱的系统”这一事实毫无意义。在整个集成系统方面,一旦您检测到问题,您的代码就不是一个脆弱且明显高效的地方,可以“修复”数据。是的旧模块将继续GIGO到其他较小的系统,但那些与您的新模块相结合的遗留模块是一个有凝聚力的整体,因此构成“系统”。

这里典型的真正问题只是编写所有修复代码与新功能的时间/价值等式。这是一场不同的辩论。但是如果你有时间,而且你知道你可以做些什么来清理收到的数据,那么“你接受的是自由的”是合理的政策。

答案 3 :(得分:2)

我不会理解原因,但你是对的。

根据我的经验,PHB缺少必须理解为什么失败快速具有优点所需的大脑部分和“健康”所定义的“健壮性” - 如果必要的话,它需要吃错误 - 如果必要的话,这是一个坏主意。这是没有希望的。他们只是没有硬件来解决它。他们倾向于说“你能说得好,但用户怎么样” - 这只是他们think of the children的版本,并表示随着时间的推移,转换的结束。

我的建议是站稳脚跟。永远。

答案 4 :(得分:1)

谢谢大家。提示这个问题的案例很好地结束了,部分归功于我从上面的答案得到的见解。

我最初的反应是坚持快速失败,但我更多地考虑了这一点,并得出结论,我的模块的一个角色是为系统的其余部分提供稳定锚。这并不一定意味着接受不良数据,而是表现出问题,隔离问题并以透明的方式处理它们,直到我们找到解决方案。

我计划为这种情况添加一个新的处理程序和代码路径,这将正确执行,就好像它是一个以前未记录的特殊用例。

我们在讨论中重申了在边界处理问题的必要性,但也愿意提供帮助。我向另一方概述了我的计划,因为我怀疑我的立场被认为过于迂腐,并且解决方案被认为是我只需要关闭无害数据的虚假验证,即使它是不正确的。实际上,我的工作方式主要是数据驱动,所以我解释了为什么它必须是正确的以及行为是如何驱动的,以及如何适应这些数据我将实现一个特殊的代码路径。

我认为这对我的立场起了重要作用,这导致对另一方对修复数据的厌恶进行了更彻底的讨论。事实证明,处理容易出错的遗留系统比处理实际障碍更令人厌倦。有一个相对简单的解决方案,改变是一种可怕的想法,这是一种相当根深蒂固的心态。

但是,在播出所有挑战和可能的解决方案之后,我们最终同意修复数据,到目前为止它似乎已经解决了我们的问题。我们的集成测试现在一直在通过,但我们还添加了日志记录并将继续监控它。

总之,我认为对我来说,这两个原则的综合是快速失败对表面问题至关重要。但是一旦它们浮出水面,强健就意味着提供一条透明的路径,以不损害系统的方式继续运行。我能够提供这一点,并通过这样做,赢得了另一方的一些善意,并最终修复了数据。

再次感谢所有回复的人。我太新了评论评论,但我很欣赏所有的观点。

答案 5 :(得分:0)

这是一个棘手的问题。如果你的模块收到了错误的数据,并且“你没有对它们做任何事情并且返回”,那么我建议你写错误日志而不是向用户显示错误。

答案 6 :(得分:0)

这取决于你得到的错误类别。如果系统中断的方式意味着您可以继续运行而不会将错误数据提供给系统的任何其他部分,那么您应该尽一切力量处理所提供的任何输入。

在我看来,尽管数据纯度胜过工作系统,但您不能允许不良数据传播到其他地方并破坏其他系统。在某种程度上,你可以按摩数据是正确的,然后继续前进,你应该根据数据是安全的理论这样做,你必须保持系统运行......

我喜欢用数据流来思考问题。传递不良数据会污染整个流,这很糟糕,因为就像真正的污染一样,丢弃会破坏整个数据流(如果一个元素不好,还有什么可以信任?)。但同样糟糕的是阻止流动,因为你发现了一些你可以轻易删除的东西,所以没有任何结果。过滤掉它,如果每个阶段的每个人都是过滤器,即使中间开始有一些杂质,你也可以从另一端得到清晰的数据。

答案 7 :(得分:0)

同行提出的问题是:“你为何不解决这个问题”

您说您可以检测到错误数据,并向用户报告错误。这是正常的方法 - 一旦你知道进入你的功能的数据是坏的,你应该快速失败(这是我在这里读到的其他答案的建议)。

但是,您的问题未指定软件运行的域。如果您知道进入的数据是错误的,您是否可以再次请求该数据?实际上是否有可能从这种情况中恢复过来?

我提到这里的“域名”很重要。因此,如果您有一个显示流式视频数据的应用程序,并且您的无线信号可能很弱,因此流已损坏,系统是否“快速失败”并显示错误消息?或者是否应显示较差的图像,并根据问题的严重程度尝试重新连接(如果需要)?

根据您的域,您可能会检测到错误数据,并对数据进行第二次请求,而不会给用户带来不便。 (这显然只适用于您希望第二次数据更好的情况,但您确实说您遇到的问题是间歇性的并且可能与并发相关)...

所以,快速失败是好的,如果你无法恢复,肯定是你应该做的事情。你绝对不应该传播不良数据。但如果你可以恢复,在某些领域可以恢复,那么立即失败并不一定是最好的事情。

相关问题