2011-08-22 5 views
33

Nella mia applicazione Web ci sono alcune richieste che durano più di 20 secondi. Ma in alcune situazioni il codice può portare a loop infiniti o qualcosa di simile che rallenta il server.Timeout richiesta Tomcat

Voglio mettere un timeout di richiesta per 60 secondi sul lato server. È implementato in Tomcat?

Grazie, Horatiu

+0

State usando '' Socket' e ServerSocket'? perché se lo sei, puoi impostare il timeout con il metodo 'SetSoTimeout'. –

+0

Just plain tomcat –

+0

@Eran, sta sviluppando un'applicazione web. Non può accedere al socket del server aperto da Tomcat. – AlexR

risposta

37

Con Tomcat 7, è possibile aggiungere StuckThreadDetectionValve che consente di identificare i thread "bloccati".È possibile set-up della valvola nell'elemento contesto delle applicazioni in cui si desidera fare il rilevamento:

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

Questo sarebbe scrivere un WARN ingresso nel Tomcat di log per tutti i thread che richiede più di 60 secondi, che avrebbe consente di identificare le applicazioni e vietarle perché sono difettose.

In base allo source code potresti essere in grado di scrivere la tua valvola che tenta di interrompere il thread, tuttavia ciò avrebbe effetti di trascinamento sul pool di thread e c'è no reliable way di arresto di un thread in Java senza la cooperazione di quello filo ...

+1

Invece di uccidere quel thread (che non è affidabile come hai detto), lanciare un runtimeexception è sufficiente –

9

È possibile impostare l'intervallo di tempo predefinito nel 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"/> 
+0

C'è un modo per influenzare solo la mia applicazione? –

+1

Purtroppo non è possibile effettuare il timeout dal server AFAIK I potrebbe essere errato – Chris

+6

La connessioneTimeout indica per quanto tempo Tomcat attenderà la riga di richiesta http una volta stabilita una connessione. Non influisce sul tempo di attesa del completamento della richiesta da parte del server – Dave

19

Se si sta cercando di evitare che una richiesta di esecuzione troppo a lungo, quindi impostando un timeout in Tomcat non ti aiuterà. Come dice Chris, puoi impostare il valore di timeout globale per Tomcat. Ma, da The Apache Tomcat Connector - Generic HowTo Timeouts, vedere la sezione Timeout risposta:

JK può anche utilizzare un timeout su richiesta risposte. Questo timeout non corrisponde a per misurare il tempo di elaborazione completo della risposta. Invece controlla, quanto tempo è consentito tra pacchetti di risposta consecutivi.

Nella maggior parte dei casi, questo è ciò che in realtà si desidera. Si consideri ad esempio il download di lunga durata . Non è possibile impostare un timeout di risposta globale valido, perché i download possono durare per molti minuti. La maggior parte delle applicazioni ha un tempo di elaborazione limitato prima di avviare per restituire la risposta. Per tali applicazioni è possibile impostare un timeout di risposta esplicito . Le applicazioni che non si armonizzano con i timeout della risposta sono applicazioni di tipo batch, data warehouse e reporting di applicazioni che prevedono lunghi tempi di elaborazione.

Se JK interrompe l'attesa di una risposta, poiché è stato generato un timeout di risposta, , non è possibile interrompere l'elaborazione nel back-end. Sebbene tu possa liberare le risorse di elaborazione nel tuo server web, la richiesta continuerà fino al eseguito sul back-end, senza alcun modo di inviare un risultato dopo il licenziamento del timeout di risposta .

Così Tomcat rileverà che il servlet non ha risposto entro il timeout e invierà una risposta per l'utente, ma non si fermerà il filo conduttore. Non penso che tu possa ottenere quello che vuoi fare.

+0

Forse in jboss? Il motore di Google App ha fatto questo, 30 secondi o qualcosa del genere –

+3

Il link non è aggiornato – rouan

1

Questo articolo spiega come impostare i timeout a livello di server. http://www.coderanch.com/t/364207/Servlets/java/Servlet-Timeout-two-ways

Che cosa sta causando l'applicazione in loop infinito? Se si aprono connessioni ad altre risorse, è possibile che si desideri impostare i timeout su tali connessioni e inviare una risposta appropriata quando si verificano tali timeout.

+0

Perché c'è un markdown su questo? La risposta è pertinente alla domanda posta lì. – thcricketfan

+4

Suppongo che sia stato rifiutato perché l'articolo riguarda ** timeout sessione ** –

-6

Aggiungi Tomcat in Eclipse

in Eclipse, come server Tomcat, doppio clic su "Tomcat v7.0 Server at localhost", modificare le proprietà come mostrato in time out impostazioni 45 a qualunque sec che ti piace

+2

Stai forse mixando il timeout di avvio del server con il richiesta timeout? La domanda –

+0

sta parlando del timeout della richiesta http, non del timeout di avvio/arresto –

-1

Per chi non ama nessuna delle soluzioni po come sopra, puoi semplicemente implementare un timer tu stesso e interrompere l'esecuzione della richiesta lanciando un'eccezione di runtime. Qualcosa come di seguito:

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

o, preferibilmente, utilizzare il Java guava timeLimiter here

+1

per cui è valido il downvote? – george