Problem mit Verbindungsaufbau via URLConnection

gburi

Grünschnabel
Hallo.

Ich habe ein Problem unter Windows XP (java 1.6.0 04). Da längere Vorgeschichte im Bereich Lasttests einer Webapplication, hier nur die Kurzversion:

Ich habe ein Client-Programm, dass 5 Childthreads öffnet. Jeder Childthread macht eine URLConnection zu einem Port auf der lokalen Maschine auf, auf dem KEIN Server läuft. Erwarten würde ich, dass jeder Konnektierungsversuch sofort mit einer ConnectException zurückkehrt. Dies ist aber nicht immer der Fall. Reproduzierbar kommt es immer wieder mal dazu, dass es ziemlich genau 60 Sekunden dauert, bis die Exception geworfen wird (es sind IMMER ziemlich genau 60 Sekunden).

Hier mal der Output eines Testlaufs. Jede Zeile mit einem einzelnen "." bedeutet 5 Sekunden Wartezeit (der Hauptthread checkt alle 5 Sekunden, ob alle ChildThreads beendet sind).

Start Test...
Thread 0 started...
Thread 1 started...
Thread 2 started...
Thread 3 started...
Thread 4 started...
.
3+java.net.ConnectException
1+java.net.ConnectException
0+java.net.ConnectException
2+java.net.ConnectException
.
.
.
.
.
.
.
.
.
.
.
.
4+java.net.ConnectException
THREAD 4 -> 60953ms


RESULTS:
ThreadIndex;NumIterations;NumErrors;MinReqT;MaxReqT;AvgReqT
Thread 0;1;1;1016;1016;1016
Thread 1;1;1;1016;1016;1016
Thread 2;1;1;1016;1016;1016
Thread 3;1;1;984;984;984
Thread 4;1;1;60953;60953;60953
END!


Falls Ihr Euch jetzt fragt, warum ich versuche auf einen Port zu connecten, auf dem nichts läuft: Damit ist der Server als Fehlerquelle ausgeschlossen. Es geht mir letztlich darum herauszufinden, warum es im Client-Server-Betrieb immer mal wieder zu extrem langen Laufzeiten von Requests kommt (also die o.g. 60 Sekunden). So bin ich auf das o.g. Problem gestoßen, das wohl auch die Ursache für mein eigentliches Problem ist.
Wenn ich gegen den Server (läuft auch lokal) connecte, kommt es auch immer wieder mal dazu, dass ein Request ziemlich genau 60 Sekunden braucht, bis das Ergebnis da ist. Serverseitig kann ich aber den Zeitverlust nicht nachvollziehen (Messungen sind immer unauffällig). Die Zeit muss also beim Verbindungsaufbau verloren gehen.

Weitere Infos:
+ Im o.g. Output ist es der letztgestartete Thread. Das ist aber nur Zufall!
+ Firewall ist nicht das Problem. Das Problem tritt auch ohne Firewall auf (BitDefender)
+ Ein netstat -a zeigt mir, dass noch jede Menge TCP-Ports zur Verfügung stehen, um die Socketverbindung herzustellen.

Hat jemand eine Idee, was das Problem sein könnte bzw. was ich mal überprüfen könnte?

Update: Das Problem tritt auch auf, wenn ich direkt die Socket-Klasse benutze. Kann es sein, dass Windows XP einen TCP-Port zuweist, der gerade auf TIME_WAIT steht? Würde aber eigentlich meinen TCP-Settings widersprechen da TcpTimedWaitDelay auf 30 Sekunden eingestellt ist, ich aber immer wieder diese 60 Sekunden + x ms messe, bis die Exception kommt.
Habe das ganze gerade nochmal mit frisch gestartetem Rechner probiert. Schon beim zweiten Durchlauf blieb ein

Socket sock = new Socket("127.0.0.1", 8071);

für 60 Sekunden hängen, bis die Exception kam.


Update2:
Die Zeit geht in der java.net.PlainSocketImpl Klasse verloren und zwar beim Aufruf der nativen Methode

private native void socketConnect(InetAddress address, int port, int timeout)

aus

private synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {...}

heraus.

Hat jemand eine Idee, wie ich das Problem weiter analysieren könnte?


Danke und Gruss,

Oliver.
 
Zuletzt bearbeitet:
Hallo,


der lange Verbindungsaufbauversuch könnte an einem lahmen DNS-Server liegen (sofern du den Server nicht mit localhost / 127.0.0.1 ansprichst...).
Gehts schneller wenn du den Server über IP ansprichst?
Versuch mal deine Anwendung mit -Dnetworkaddress.cachel=0 zu starten.

Gruß Tom
 
Danke für die Antwort.

Der Client macht die Socketverbindung auf einen lokalen TCP Port auf. Dabei verwende ich 127.0.0.1.

Das Setzen von
-Dnetworkaddress.cachel=0
hat nichts gebracht.

Ich glaube entscheidend ist der Umstand, dass es immer (d.h. in den Fällen, in denen es zum Delay kommt) exakt 60 Sekunden (+ x ms) dauert bis der Call der nativen socketConnect-Methode zurückkehrt. Im Normalfall (ca. 95% der Fälle) läuft ja auch alles wie erwartet.
Kennt sich jemand mit der net.dll aus? Ggf. ist das ein bekannter Wert für den sich der Thread unter bestimten Umständen schlafen legt, bevor er überprüft, ob die Socket-Verbindung hergestellt ist?
 
Danke für die Antwort.

Das hilft leider nur bedingt. Klar kann ich bei eigenen Socket-Verbindungen Timeouts setzen. Die Sache ist aber die, dass sich das Problem wahrscheinlich auch auf die (sehr komplexe) Server-Applikation auswirkt (Datenbank-Kommunikation, Aufruf von Webservices, etc.), die auf dem gleichen Testrechner läuft und auch die gleiche Java Installation nutzt.
Auf die dort aufgemachten Socket-Verbindungen habe ich aber keinen Einfluss.
 

Neue Beiträge

Zurück