Java HttpURLConnection InputStream.close () hängt (oder arbeitet zu lange?)

8

Zuerst etwas Hintergrund. Es gibt einen Arbeiter, der eine Menge kurzer URLs erweitert / löst:

%Vor%

Wir folgen also nur Weiterleitungen. Das ist es. Wir lesen keine Daten von der Verbindung. Gleich nachdem wir 200 bekommen haben, geben wir die finale URL zurück und schließen InputStream.

Nun das Problem selbst. Auf einem Produktionsserver hängt einer der Resolver-Threads innerhalb des InputStream.close() -Aufrufs:

%Vor%

Nach kurzer Recherche habe ich verstanden, dass skip() aufgerufen wird, um den Stream zu bereinigen, bevor er zurück zum Verbindungspool gesendet wird (wenn Keep-Alive aktiviert ist?). Dennoch verstehe ich nicht, wie ich diese Situation vermeiden kann. Außerdem bezweifle ich, dass es in unserem Code ein schlechtes Design gibt oder dass es in JDK ein Problem gibt.

Die Fragen lauten also:

  1. Ist es möglich, das Hängenbleiben an close() zu vermeiden? Garantie einiger angemessener Timeout zum Beispiel.
  2. Ist es möglich, das Lesen von Daten aus der Verbindung überhaupt zu vermeiden? Denken Sie daran, ich möchte nur die endgültige URL. Eigentlich denke ich, ich will nicht skip() soll überhaupt aufgerufen werden ...

Aktualisierung:

KeepAliveStream , Zeile 79, close() Methode:

%Vor%

Mehr und mehr scheint mir, dass es einen Fehler in JDK selbst gibt. Leider ist es sehr schwierig, dies zu reproduzieren ...

    
Shcheklein 17.01.2013, 12:16
quelle

3 Antworten

5

Die Implementierung von KeepAliveStream , die Sie verknüpft haben, verstößt gegen den Vertrag, bei dem available() und skip() garantiert nicht blockierend sind und daher möglicherweise blockieren.

Der Vertrag von available () > garantiert eine single nicht blockierende skip() :

  

Gibt eine Schätzung der Anzahl der Bytes zurück, die gelesen werden können (oder   übersprungen) von diesem Eingangsstrom ohne Blockierung durch den nächsten   Aufrufer einer Methode für diesen Eingabestrom. Der nächste Anrufer könnte sein   der gleiche Thread oder ein anderer Thread. Ein einzelnes Lesen oder Überspringen von diesem   Viele Bytes blockieren nicht, können aber weniger Bytes lesen oder überspringen.

Wobei die Implementierung skip() mehrmals pro einzelnen Aufruf an available() :

aufruft %Vor%

Dies beweist nicht, dass Ihre Anwendung blockiert, weil KeepAliveStream InputStream falsch verwendet. Einige Implementierungen von InputStream können möglicherweise stärkere nicht blockierende Garantien bieten, aber ich denke, dass dies ein sehr wahrscheinlicher Verdächtiger ist.

BEARBEITEN: Nach etwas mehr Recherche ist dies ein kürzlich behobener Fehler in JDK: Ссылка . Der Fehlerbericht sagt über eine Endlosschleife aus, aber eine Blockierung skip() könnte auch ein Ergebnis sein. Das Update scheint beide Probleme zu beheben (es gibt nur ein einziges skip() pro available() )

    
Jan Wrobel 30.01.2013, 16:02
quelle
2

Ich denke, dass skip() auf close() für Keep-Alive-Unterstützung gedacht ist.

Siehe Ссылка .

  

Vor Java SE 6, wenn eine Anwendung einen HTTP InputStream schließt, wenn   mehr als eine kleine Menge von Daten bleibt zu lesen, dann die   Die Verbindung musste geschlossen und nicht zwischengespeichert werden. Jetzt in Java SE   6, das Verhalten ist bis zu 512 kbytes von der Verbindung in a zu lesen   Hintergrund-Thread, so dass die Verbindung wiederverwendet werden kann. Das   Die genaue Menge der Daten, die gelesen werden können, ist konfigurierbar über    http.KeepAlive.remainingData Systemeigenschaft.

Also am Leben zu halten kann effektiv mit http.KeepAlive.remainingData=0 oder http.keepAlive=false deaktiviert werden. Dies kann sich jedoch negativ auf die Leistung auswirken, wenn Sie sich immer an denselben Ссылка Host wenden.

Wie @artbristol vorgeschlagen hat, scheint HEAD anstelle von GET die bevorzugte Lösung zu sein.

    
Vadzim 17.01.2013 14:28
quelle
0

Ich hatte ein ähnliches Problem, als ich versuchte, eine "HEAD" -Anfrage zu stellen. Um es zu beheben, habe ich die Methode "HEAD" entfernt, weil ich nur die URL pingen wollte

    
Sabaat Ahmad 02.11.2014 10:06
quelle

Tags und Links