简体   繁体   English

在调度程序中捕获Throwable是一种好习惯吗?

[英]Is catching Throwable in schedulers a good practice?

I rather say that fail fast and not catching Throwable is a good practice. 我宁愿说快速失败并且没有捕捉Throwable是一个很好的做法。 But in case unhandled exception in request processor like StackOverflowError, the task may be stopped. 但是,如果请求处理器(如StackOverflowError)中出现未处理的异常,则可能会停止该任务。 And that doesn't always sound good. 这并不总是听起来不错。 I'd rather catch StackOverflowError over and over, but some tasks might be processed. 我宁愿一遍又一遍地捕获StackOverflowError,但可能会处理一些任务。 What is good practice here? 这里的好习惯是什么?

There is no "good practice" or "best practice" 1 about catching Error and hence Throwable . 关于捕获Error并因此Throwable没有“良好实践”或“最佳实践” 1

  • On the one hand, a JVM can recover successfully from some kinds of Error in some circumstances. 一方面,在某些情况下,JVM可以从某些类型的Error中成功恢复。 For example, if you are running "task" on a single thread that doesn't interact with other threads (directly or indirectly), then that thread can safely recover from a StackOverflowError and possibly 2 a OutOfMemoryError . 例如,如果你在一个单独的线程,不与其他线程(直接或间接)交互运行的“任务”,则该线程可以安全地从一个恢复StackOverflowError并可能2 OutOfMemoryError

  • On the other hand, many Error subclasses indicate that the application or JVM is in a state where recovery is not possible, or not practical: 另一方面,许多Error子类表明应用程序或JVM处于无法恢复或不可行的状态:

    • A class loading or initialization Error means that certain classes will be an unusable state. 类加载或初始化Error意味着某些类将处于不可用状态。 An application that depends the class won't be able to proceed. 依赖于类的应用程序将无法继续。
    • If an application that uses notify / wait or higher level synchronization constructs gets (say) an OutOfMemoryError error on one thread, it is liable to leave other threads waiting for notifications, etc that may never arrive. 如果使用通知/等待或更高级别同步构造的应用程序在一个线程上获得(比方说) OutOfMemoryError错误,则可能会让其他线程等待可能永远不会到达的通知等。

My recommendation would be to heed the implied advice in the javadoc for Error and not to catch and attempt recover from Error or its subclasses. 我的建议是注意javadoc中隐含的Error建议,而不是捕获并尝试从Error或其子类中恢复。 If you attempt to recover, allow for the possibility that the application may "wedge". 如果您尝试恢复,请考虑应用程序可能“楔入”的可能性。


1 - Actually, there is not "best practice" at all; 1 - 实际上,根本没有“最佳实践”; see https://www.satisfice.com/blog/archives/5164 请参阅https://www.satisfice.com/blog/archives/5164

2 - This depends on the root cause. 2 - 这取决于根本原因。 If the root cause is a memory leak elsewhere in your codebase, then recovery is a bad idea. 如果根本原因是代码库中其他地方的内存泄漏,那么恢复是一个坏主意。 The OOME is likely to recur ... with increasing frequency. OOME很可能会再次出现......频率越来越高。

This is from the javadoc of Error : 这是来自错误的javadoc:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Error是Throwable的子类,表示合理的应用程序不应该尝试捕获的严重问题。

I usually follow this rule to avoid suppressing real unexpected errors that should be fixed. 我通常遵循此规则以避免抑制应修复的实际意外错误。
You mentionned StackoverflowError , if you have this kind of error, there's probably a problem with your algorithm and your code should be optimized. 你提到StackoverflowError ,如果你有这种错误,你的算法可能有问题,你的代码应该优化。

If you know that a specific error is likely to be thrown and you're okay with that, you can catch it. 如果你知道可能会抛出一个特定的错误并且你对此感到满意,你就可以捕获它。 However if you don't expect it, it's better to raise the alarm ASAP and deal with it. 但是,如果你不期望它,最好尽快提高警报并处理它。

Good practice is catch scheduled jobs, write log about exception, metrics and(optional) reschedule it. 好的做法是捕获预定的作业,写关于异常的日志,指标和(可选)重新安排它。

Also, sometimes your thread will be stoped/destroyed (hello spring schedulers) cause you receive some sort of exception, that not critical to your job... 此外,有时您的线程将被停止/销毁(hello spring schedulers)导致您收到某种异常,这对您的工作并不重要......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM