52

In my web application there are some requests which last longer than 20 seconds. But in some situations the code can lead to infinite loop or something similar which slows down the server.

I want to put a request timeout for 60 sec on the server side. Is this implemented in tomcat?

7
  • Are you using Socket and ServerSocket? because if you are, you can set the timeout there with the SetSoTimeout method. Commented Aug 22, 2011 at 9:01
  • @Eran, he is developing web application. He cannot acess server socket opened by Tomcat. Commented Aug 22, 2011 at 9:07
  • 2
    I'd really challenge the fact that you have deployed code that sometimes leads to infinite loops :-) Commented Aug 22, 2011 at 15:27
  • 1
    I'd start by fixing the infinite loop(s). Having the session timeout while your code is looping around will not change the fact that it is looping around. Commented Aug 22, 2011 at 17:52
  • The code will be added by other people, and I don't want their modules to go into infinite loop and slow the server down Commented Aug 23, 2011 at 23:46

6 Answers 6

55

With Tomcat 7, you can add the StuckThreadDetectionValve which will enable you to identify threads that are "stuck". You can set-up the valve in the Context element of the applications where you want to do detecting:

<Context ...> ... <Valve className="org.apache.catalina.valves.StuckThreadDetectionValve" threshold="60" /> ... </Context> 

This would write a WARN entry into the tomcat log for any thread that takes longer than 60 seconds, which would enable you to identify the applications and ban them because they are faulty.

Based on the source code you may be able to write your own valve that attempts to stop the thread, however this would have knock on effects on the thread pool and there is no reliable way of stopping a thread in Java without the cooperation of that thread...

Sign up to request clarification or add additional context in comments.

1 Comment

Instead of killing that thread (which is not reliable as you mentioned), throwing a runtimeexception is enough
30
+25

If you are trying to prevent a request from running too long, then setting a timeout in Tomcat will not help you. As Chris says, you can set the global timeout value for Tomcat. But, from The Apache Tomcat Connector - Generic HowTo Timeouts, see the Reply Timeout section:

JK can also use a timeout on request replies. This timeout does not measure the full processing time of the response. Instead it controls, how much time between consecutive response packets is allowed.

In most cases, this is what one actually wants. Consider for example long running downloads. You would not be able to set an effective global reply timeout, because downloads could last for many minutes. Most applications though have limited processing time before starting to return the response. For those applications you could set an explicit reply timeout. Applications that do not harmonise with reply timeouts are batch type applications, data warehouse and reporting applications which are expected to observe long processing times.

If JK aborts waiting for a response, because a reply timeout fired, there is no way to stop processing on the backend. Although you free processing resources in your web server, the request will continue to run on the backend - without any way to send back a result once the reply timeout fired.

So Tomcat will detect that the servlet has not responded within the timeout and will send back a response to the user, but will not stop the thread running. I don't think you can achieve what you want to do.

1 Comment

Perhaps in jboss ? Google app engine has done this, 30 second or something like that
7

You can set the default time out in the 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"/> 

4 Comments

Is there a way to affect only my application ?
You cant effect the timeout from the server unfortunately AFAIK I may be wrong
The connectionTimeout is how long Tomcat will wait for the http request line once a connection is established. It doesn't affect how long the server waits for the request to finish processing
See also stackoverflow.com/a/45380028/32453 apparently there is a "kind" of writeTimeout you can control FWIW.
0

This article talks about setting the timeouts on the server level. http://www.coderanch.com/t/364207/Servlets/java/Servlet-Timeout-two-ways

What is causing the application to go into infinite loop? If you are opening connections to other resources, you might want to put timeouts on those connections and sending appropriate response when those time out occurs.

2 Comments

Why is there a markdown on this? The answer is relevant to the question posted there.
I guess it was voted down because the article is about session timeouts
0

For anyone who doesn't like none of the solutions posted above like me then you can simply implement a timer yourself and stop the request execution by throwing a runtime exception. Something like below:

 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"); } 

or preferably use the java guava timeLimiter here

Comments

-9

Add tomcat in Eclipse

In Eclipse, as tomcat server, double click "Tomcat v7.0 Server at Localhost", Change the properties as shown in time out settings 45 to whatever sec you like

2 Comments

Are you maybe mixing the server starting timeout with the request timeout itself?
question is talking about http request timeout , not the start/stop timeout

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.