2012-04-01 6 views
5

Einige seltsame Situation. Während eines Leistungstests einer Web-Anwendung (Krieg) erhält der Client 500 auf etwa 2% der Anfragen. Wenn Sie das Anwendungsprotokoll der Suche, es gibt es einige Ausnahmen:Fehlende Fehleranforderungen im Protokoll localhost_access des Tomcat, während IOException während des Aufrufs von Jackson im Anwendungsprotokoll erscheint

java.io.IOException: Stream closed 
    at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:394) 
    at org.apache.catalina.connector.CoyoteReader.read(CoyoteReader.java:110) 
    at org.codehaus.jackson.impl.ReaderBasedParserBase.loadMore(ReaderBasedParserBase.java:95) 
    at org.codehaus.jackson.impl.ReaderBasedParser._skipWSOrEnd(ReaderBasedParser.java:935) 
    at org.codehaus.jackson.impl.ReaderBasedParser.nextToken(ReaderBasedParser.java:245) 
    at org.codehaus.jackson.map.ObjectMapper._initForReading(ObjectMapper.java:2432) 
    at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2389) 
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1618) 
    at MyServlet.doPost(MyServlet.java:25) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at MyFilter.doFilter(MyFilter.java:67) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at MyFilter.doFilter(MyFilter.java:28) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:304) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 

Allerdings ist die localhost_access leer und es werden alle Anforderungen 200-Statuscode.

Ich werde keine Erkenntnisse über dieses Problem zu schätzen wissen:

  • Wie das localhost_access log 500 Anfragen fehlt passieren kann, während der Kunde ihnen. Wann passiert das überhaupt?
  • Warum java.io.IOException wird nur gelegentlich (weniger als 2% der Anfragen) geworfen?

Update 1: Das Problem mit Tomcat 7.0.22 tritt und Java 6

Update 2: Hier einige Beispiel-Anfrage auf eine statische HTML-Datei (nicht einmal auf ein Servlet, so gibt in Protokoll- und nichts ist keine Ausnahme in localhost_access):

Response headers: 
HTTP/1.1 500 Internal Server Error 
Server: Apache-Coyote/1.1 
Content-Type: text/html;charset=utf-8 
Transfer-Encoding: chunked 
Date: Mon, 02 Apr 2012 07:35:06 GMT 
Connection: close 

Update 3: das Netzwerk ich die gleichen Tests auf dem lokalen Host lief zu beseitigen. Es hat die Testergebnisse nicht beeinflusst. Es ist also nicht das Netzwerk.

Update 4: Neustart von Tomcat half. Und ich verstehe immer noch nicht, was das ursprüngliche Problem verursacht hat.

Update 5: Tomcat aktualisiert auf 7.0.26, aber es hat das Problem nicht gelöst.

Update 6: Zum Jetty bewegt. Die Fehler sind weg. Soll ich Tomcat nach all den Jahren "Auf Wiedersehen" sagen?

+0

Wird der Stack-Trace für einen dieser Fehler über dem vollständigen Stack-Trace angegeben? Wenn nicht, könnten Sie bitte den vollständigen Stack-Trace bereitstellen. –

+0

Vollständiger Stacktrace hinzugefügt. Ich habe unsere benutzerdefinierten Klassen durch MyServlet und MyFilter ersetzt. – Tarlog

+0

Gibt es eine Chance, dass Ihr Filter einen Verweis auf die Anfrage beibehält und ein Anfrageobjekt verwendet, das mit einer früheren Anfrage als der aktuellen verknüpft ist? –

Antwort

5

Sie sagen nicht, welche Version von Tomcat Sie laufen, die eine große Hilfe wäre. Meine Vermutung - basierend auf dem, was Sie sehen - ist, dass es relativ alt ist.
Das Zugriffsprotokoll ist als Ventil implementiert. Wenn eine Anforderung abgelehnt wird, bevor sie bis zu den Ventilen gelangt, wird sie niemals im Zugriffsprotokoll angezeigt. Dies tritt normalerweise auf, wenn die Anforderung fehlerhaft ist, aber es gibt andere Umstände, die sie auslösen könnten.
Ab Tomcat 6.0.30 (und allen 7.0.x-Versionen) wurde der Zugriffsprotokollierungsmechanismus überarbeitet, um sicherzustellen, dass Nachrichten in das Zugriffsprotokoll geschrieben werden, auch wenn die Anforderung zurückgewiesen wird, bevor sie AccessLogValve erreicht.

Die IOException wird ausgelöst, wenn der Client die Verbindung schließt. Ob das wegen der 500 ist oder die 500 verursacht ist unklar aus den bereitgestellten Informationen.

+0

Es ist Tomcat 7.0.22 (übrigens, ich habe das Tomcat7-Tag, aber Sie haben wahrscheinlich Recht, ich sollte es explizit schreiben) – Tarlog

+0

In Bezug auf "IOException wird ausgelöst, wenn der Client die Verbindung schließt". Wie erhält der Kunde in diesem Fall 500 von Tomcat? Ziemlich unklar. – Tarlog

4

Fehlermeldung zeigt an, dass IOException richtig kommt, wenn Jackson versucht, das Parsen zu initialisieren, was bedeutet, dass die zugrunde liegende HTTP-Verbindung bereits geschlossen ist, wenn mit der Analyse der Anfrage begonnen wird. Also hat etwas die Verbindung geschlossen; und obwohl es sowohl Client als auch Server sein könnte (HTTP erlaubt es beiden Enden, Verbindungen an jedem Punkt zu schließen), ist es oft etwas in der Mitte (Firewall, Proxy, Loadbalancer); oft aufgrund einer Auszeit irgendeiner Art.

+0

Ja, meine erste Vermutung, dass es ein Loadbalancer war. Die Verbindung mit dem Tomcat führte jedoch direkt zum selben Fehler. Mein Gefühl immer noch, dass es "netzwerkbezogen" ist, aber ich habe keine Ahnung, wie ich es angehen soll. – Tarlog

+0

Getestet auf localhost. Derselbe Fehler wurde reproduziert. Es ist also nicht netzwerkbezogen. Es ist Tomcat. – Tarlog

+0

Eine Sache, die Sie tun können, ist, zuerst das Bit der Eingabe (oder das Ganze) zu lesen, um den Fall zu behandeln, dass Sie keinen Inhalt bekommen; und wenn du Inhalt gepuffert bekommst, gib das nur an Jackson weiter. Auf diese Weise können Sie zumindest bessere Fehlermeldungen erhalten. Natürlich möchten Sie auch herausfinden, warum dies passiert, aber es macht Sinn, auch bessere Fehlermeldungen zu liefern? – StaxMan

1

AJAX Post auf IE haben intermittierende Fehler. Wir haben sockettimeoutceptions gesehen. Sie können KeepAlive deaktivieren und versuchen, KeepAlive für AJAX POST zu deaktivieren, indem Sie eine 'connection: close'-Kopfzeile verwenden. Tune Apache requestreadtimeout für keine Körperanfrage.

+0

Nun, ich bin seither nach Jetty gezogen. Es ist viel viel besser. – Tarlog