18

我们的产品是一个分布式系统。我工作的模块是相当新的、相当严格的、经过良好测试的。它们的开发考虑了最近的最佳实践。其他模块可以被视为遗留软件。

虽然我对我负责的模块中发生的一切保持警惕,但我一直承受着处理从其他模块发送给我的不良数据的压力。本质上,我是一个“快速失败”的原则开发人员,因此,当出现问题时,我通常能够消除模块中出错的可能性。与其说是责备,不如说是为了避免在错误的地方追逐错误而浪费精力。

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

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

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

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

那么,我需要更加务实还是坚守自己的立场?

4

8 回答 8

4

我分享“快速失败”的偏好/原则。不要认为这是原则上的冲突,更多的是理解上的冲突。您的对方有一些未说出口的要求(“不要向用户展示糟糕的时间”),这意味着一些错过的要求。您没有机会事先考虑/实施此要求,因此该要求在您的嘴里留下了不好的味道。忘记这个观点,把它当作一个新项目来重新对待,你可以解决一个固定的需求。

也许最好的结果是像您显示的那样给出错误消息。但听起来你在得到对方的支持之前实施了它,当时他们可以选择接受它。关于你在做什么的早期沟通可能会解决类似的问题。

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

于 2010-01-28T07:44:35.497 回答
3

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

如果可能的话,把你的蛋糕也吃掉——不要向用户报告错误,让客户同意发送诊断报告并报告每个故障。对拥有故障模块的开发人员进行错误修复以修复它们。我所说的错误是指针对他们提出错误。或者,如果管理层认为修复成本不值得,那就不要。

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

但真正归结为审查你表现的人想要你做什么,尤其是在你通过电子邮件向他们解释问题之后。

于 2010-01-28T07:30:29.257 回答
2

简而言之,这听起来像是“不要检查您无法处理的事情”。您发现错误并能够报告它的事实意味着您没有传播它。但这也意味着,既然你可以报告它,你就有一些机制来捕获错误,因此可能会自己处理它,并纠正它而不是报告它。

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

最重要的是,你需要两者。您需要尽量使数据尽可能无错误,但也要报告意外情况。

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

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

于 2010-01-28T07:37:31.893 回答
2

我不会详细说明原因,但你是对的。

以我的经验,PHB 缺少理解为什么快速失败具有优点和“稳健性”所需的大脑部分,正如 do-whatever-it-takes-eat-eat-errors-if-necessary 是一个坏主意所定义的那样。这是没有希望的。他们只是没有硬件来摸索它。他们倾向于说“好吧,你说得很好,但用户呢?”——这只是他们对孩子们的看法,并在任何时候向我发出转换的信号。

我的建议是坚持你的立场。永远。

于 2010-01-28T07:39:07.560 回答
1

谢谢大家。引发这个问题的案例结束得很好,部分归功于我从上面的答案中获得的见解。

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

我计划为这个案例添加一个新的处理程序和代码路径,它可以像以前未记录的特殊用例一样正确执行。

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

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

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

In summary, I think that for me, the synthesis of both principles is that fail fast is essential for surfacing problems. But once they do surface, robustness means providing a transparent path to continue operation in a way that does not compromise the system. I was able to offer that, and by doing so, won some goodwill from the other side and got the data fixed in the end.

Again, thanks to everyone that responded. I'm too new to rate comments, but I do appreciate all the perspectives presented.

于 2010-01-30T08:36:06.303 回答
0

这是一个棘手的问题。如果您的模块接收到错误数据并且您可以对它们不执行任何操作并返回,那么我建议您写入错误日志而不是向用户显示错误。

于 2010-01-28T07:32:16.117 回答
0

这取决于您遇到的错误类别。如果系统崩溃的方式意味着您可以继续运行而不会向系统的任何其他部分提供不良数据,那么您应该尽您所能处理所提供的任何输入。

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

我喜欢从数据流的角度来思考问题。传递不良数据会污染整个数据流,这很糟糕,因为就像真正的污染一样,一滴水就会破坏整条数据河(如果一个元素不好,你还能相信什么?)。但同样糟糕的是阻塞流动,什么都没有通过,因为你发现了一些你可以轻松移除的东西。把它过滤掉,如果每个阶段的每个人都在过滤,即使中间开始有一些杂质,你也会从另一端得到清晰干净的数据。

于 2010-01-28T08:11:09.613 回答
0

你的同龄人的问题是:“你为什么不解决这个问题”

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

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

我提到这里的“域”很重要。因此,例如,如果您有一个显示流式视频数据的应用程序,并且您的无线信号可能很弱,因此流式传输已损坏,那么系统是否应该“快速失败”并显示错误消息?还是应该显示较差的图像,并在需要时尝试重新连接,具体取决于问题的严重程度?

根据您的域,您可能会检测到不良数据,并在不给用户带来不便的情况下再次请求数据。(这显然仅在您希望第二次数据更好的情况下才相关,但您确实说您遇到的问题是间歇性的并且可能与并发相关)......

所以,fail-fast 很好,如果你无法恢复,绝对是你应该做的事情。而且您绝对不应该传播不良数据。但是,如果您可以恢复,在某些领域您可以恢复,那么立即失败不一定是最好的选择。

于 2010-01-28T08:40:57.590 回答