在我的 Web 应用程序中,有些请求持续时间超过 20 秒。但在某些情况下,代码可能会导致无限循环或类似的情况,从而降低服务器速度。
我想在服务器端设置一个 60 秒的请求超时。这是在tomcat中实现的吗?
使用 Tomcat 7,您可以添加 StuckThreadDetectionValve,这将使您能够识别“卡住”的线程。您可以在要进行检测的应用程序的上下文元素中设置阀门:
<Context ...>
...
<Valve
className="org.apache.catalina.valves.StuckThreadDetectionValve"
threshold="60" />
...
</Context>
这会针对任何耗时超过 60 秒的线程在 tomcat 日志中写入 WARN 条目,这将使您能够识别应用程序并禁止它们,因为它们有问题。
基于源代码,您也许可以编写自己的阀门来尝试停止线程,但这会对线程池产生连锁反应,并且在Java中没有没有可靠的方法来停止线程而不需要该线程的合作...
如果您试图防止请求运行太长时间,那么在 Tomcat 中设置超时将无济于事。正如 Chris 所说,您可以为 Tomcat 设置全局超时值。但是,来自 The Apache Tomcat Connector - Generic HowTo 超时,请参阅回复超时部分:
JK 还可以对请求回复使用超时。这个超时不 测量响应的完整处理时间。相反,它控制, 连续响应数据包之间允许有多少时间。
在大多数情况下,这就是人们真正想要的。例如考虑 长时间运行的下载。您将无法设置有效的 全局回复超时,因为下载可能会持续很多分钟。 大多数应用程序在开始之前的处理时间有限 返回响应。对于这些应用程序,您可以设置 显式回复超时。与回复不协调的申请 超时是批处理类型的应用程序、数据仓库和报告 预计处理时间较长的应用程序。
如果 JK 由于回复超时而中止等待响应, 无法停止后端的处理。虽然你有空 在您的网络服务器中处理资源时,请求将继续 在后端运行 - 一旦执行就没有任何方法发送回结果 回复超时被解雇。
因此 Tomcat 会检测到 servlet 在超时时间内没有响应,并将向用户发回响应,但不会停止线程运行。我认为你无法实现你想做的事情。
您可以在
server.xml
中设置默认超时
<Connector URIEncoding ="UTF-8"
acceptCount ="100"
connectionTimeout ="20000"
disableUploadTimeout ="true"
enableLookups ="false"
maxHttpHeaderSize ="8192"
maxSpareThreads ="75"
maxThreads ="150"
minSpareThreads ="25"
port ="7777"
redirectPort ="8443"/>
本文讨论在服务器级别设置超时。 http://www.coderanch.com/t/364207/Servlets/java/Servlet-Timeout-two-ways
是什么导致应用程序进入无限循环?如果您要打开与其他资源的连接,您可能希望对这些连接设置超时,并在发生超时时发送适当的响应。
对于像我一样不喜欢上面发布的解决方案的任何人,您可以简单地自己实现一个计时器,并通过抛出运行时异常来停止请求执行。如下所示:
try
{
timer.schedule(new TimerTask() {
@Override
public void run() {
timer.cancel();
}
}, /* specify time of the requst */ 1000);
}
catch(Exception e)
{
throw new RuntimeException("the request is taking longer than usual");
}
或者最好使用 java guava timeLimiter here
在Eclipse中添加tomcat
在 Eclipse 中,作为 tomcat 服务器,双击“Tomcat v7.0 Server at Localhost”,将超时设置 45 中所示的属性更改为您喜欢的秒数