【发布时间】:2019-01-29 19:15:21
【问题描述】:
我们的分布式应用程序中有一些奇怪的行为。我们尚未找到原因,但我们认为这可能与 OutOfMemory 错误有关。
但是,对于致命错误,我们尝试遵循良好的编码实践,例如从不捕获所有可抛出的错误,以及最多非致命错误。但我意识到,对于 Future 中发生的致命错误,我有些不太明白,而且我们的代码几乎都被封装到 Future 中。
这是一个最小的例子:
val f = Future{ /* some code that makes an OOM error */ }
val result = Await.result(f, 1 minutes)
会发生什么
- 运行未来代码的线程失败。 OOM 打印在 stderr 中。但是我们看不到它,因为应用程序部署在“某处”并且我们没有重定向标准错误
- 但是,Future 并没有结束(它只捕获 NonFatal)。值得它不会释放资源。
- 1 分钟后,我们得到与 OOM 无关的 TimeoutException。希望它释放资源。但是我们已经失去了时间,其他线程可能会受到影响。然后我们将其视为没有时间完成的未来。类似地,好像某些数据库访问没有及时响应,即我们通常会再试一次。
我在这里找到了一个很好的问题描述:https://github.com/scala/bug/issues/9554
我的问题:我们应该如何处理未来发生的致命错误?
- 至少,整个应用程序应该会像在主线程中发生致命错误一样失败。也许有核心转储
- 最好有适当的管理:记录异常,应用合适的重新执行模式,可能优雅地杀死其他正在运行的未来/线程,...
注意:这是与Exception causes Future to never complete 类似的问题,但答案是“这是有意的”而不是如何管理它
【问题讨论】:
-
您考虑过这个解决方案吗? stackoverflow.com/a/3878199/227803
-
不。实际上它在java中是同样的问题,这个解决方案可以在这里应用(这是我的问题的有效答案)。 OOM 是我最关心的问题,但你知道它是否可以应用于其他致命错误吗?
-
试用 Scala 2.13.0-M5 发布后,我重新处理了致命错误,但我不知道它将如何影响您的特定代码。
-
谢谢,等我出来看看
标签: scala future fatal-error