Warum sollte eine Ausnahme "java.net.ConnectException: Zeitüberschreitung der Verbindung" auftreten, wenn die URL aktiv ist?

85

Ich bekomme eine ConnectException: Connection timed outmit einer gewissen Häufigkeit von meinem Code. Die URL, die ich zu treffen versuche, ist aktiv. Der gleiche Code funktioniert für einige Benutzer, für andere jedoch nicht. Es scheint, als würde ein Benutzer, sobald er diese Ausnahme erhält, die Ausnahme weiterhin erhalten.

Hier ist die Stapelverfolgung:

java.net.ConnectException: Connection timed out
Caused by: java.net.ConnectException: Connection timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
    at java.net.Socket.connect(Socket.java:516)
    at java.net.Socket.connect(Socket.java:466)
    at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:365)
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:477)
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:214)
    at sun.net.www.http.HttpClient.New(HttpClient.java:287)
    at sun.net.www.http.HttpClient.New(HttpClient.java:299)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:796)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:748)
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:673)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:840)

Hier ist ein Ausschnitt aus meinem Code:

URLConnection urlConnection = null;
OutputStream outputStream = null;
OutputStreamWriter outputStreamWriter = null;
InputStream inputStream = null;

try {
    URL url = new URL(urlBase);
    urlConnection = url.openConnection();
    urlConnection.setDoOutput(true);

    outputStream = urlConnection.getOutputStream(); // exception occurs on this line
    outputStreamWriter = new OutputStreamWriter(outputStream);
    outputStreamWriter.write(urlString);
    outputStreamWriter.flush();
    inputStream = urlConnection.getInputStream();
    String response = IOUtils.toString(inputStream);
    return processResponse(urlString, urlBase, response);
} catch (IOException e) {
    throw new Exception("Error querying url: " + urlString, e);
} finally {
    IoUtil.close(inputStream);
    IoUtil.close(outputStreamWriter);
    IoUtil.close(outputStream);
}
Sarah Haskins
quelle
7
Bitte markieren Sie eine Antwort als erledigt, wenn Sie Ihr Problem gelöst haben :)
Tobias

Antworten:

83

Verbindungszeitüberschreitungen (unter der Annahme eines lokalen Netzwerks und mehrerer Clientcomputer) ergeben sich normalerweise aus

a) eine Art Firewall auf dem Weg, die einfach die Pakete frisst, ohne dem Absender Dinge wie "Keine Route zum Host" mitzuteilen.

b) Paketverlust aufgrund falscher Netzwerkkonfiguration oder Leitungsüberlastung

c) zu viele Anforderungen, die den Server überlasten

d) eine kleine Anzahl gleichzeitig verfügbarer Threads / Prozesse auf dem Server, was dazu führt, dass alle von ihnen belegt werden. Dies geschieht insbesondere bei Anforderungen, deren Ausführung lange dauert und die mit c) kombiniert werden können.

Hoffe das hilft.

Nervös
quelle
Was mir beim Debuggen dieses Problems geholfen hat, war das Pingen des Servers, an den ich die Anfrage gestellt habe. Ich fand heraus, dass die URL in die öffentliche IP aufgelöst wurde und nicht in die von mir beabsichtigte private IP. Eine neue Zuordnung in der Datei / etc / hosts konnte das Problem beheben. Ich füge den Kommentar hinzu, nur für den Fall, dass jemand anderes ein ähnliches Problem hat.
Bouramas
31

Wenn die URL im Webbrowser auf demselben Computer einwandfrei funktioniert, verwendet der Java-Code möglicherweise nicht den HTTP-Proxy, den der Browser zum Herstellen einer Verbindung mit der URL verwendet.

Alexander
quelle
6

Die Fehlermeldung sagt alles: Ihre Verbindung ist abgelaufen. Dies bedeutet, dass Ihre Anfrage innerhalb eines (Standard-) Zeitrahmens keine Antwort erhalten hat. Die Gründe, warum keine Antwort eingegangen ist, sind wahrscheinlich einer der folgenden:

a) Die IP / Domain oder der Port ist falsch

b) Die IP / Domain oder der Port (dh der Dienst) ist ausgefallen

c) Die Antwort auf die IP / Domain dauert länger als Ihr Standardzeitlimit

d) Sie haben eine Firewall, die Anforderungen oder Antworten an jedem von Ihnen verwendeten Port blockiert

e) Sie haben eine Firewall, die Anforderungen an diesen bestimmten Host blockiert

f) Ihr Internetzugang ist ausgefallen

g) Ihr Live-Server ist ausgefallen, dh im Falle eines "Rest-API-Aufrufs".

Beachten Sie, dass Ihr ISP möglicherweise Firewalls und Port- oder IP-Blockierungen installiert hat

M Hamza Javed
quelle
4

Ich würde empfehlen, das Zeitlimit für die Verbindung zu erhöhen, bevor der Ausgabestream abgerufen wird.

urlConnection.setConnectTimeout(1000);

Wobei 1000 in Millisekunden angegeben ist (1000 Millisekunden = 1 Sekunde).

Powerlord
quelle
21
Das erhöht es nicht, das senkt es drastisch. Standardmäßig dauert es ungefähr eine Minute, und Sie können es nicht erhöhen, sondern nur verringern.
Marquis von Lorne
3
  • Versuchen Sie, Telnet auszuführen, um ein Firewall-Problem zu erkennen
  • Führen Sie tracert/ tracerouteum die Anzahl der Sprünge zu ermitteln
bläulich
quelle
Traceroute wohin?
Flugzeug
Offensichtlich zu welcher IP auch immer Sie den Fehler bekommen haben.
John Lord
2

Ich habe mein Problem gelöst mit:

System.setProperty("https.proxyHost", "myProxy");
System.setProperty("https.proxyPort", "80");

oder http.proxyHost...

NikNik
quelle
0

Es besteht die Möglichkeit, dass Ihre IP / Ihr Host vom Remote-Host blockiert wird, insbesondere wenn er denkt, dass Sie ihn zu stark treffen.

larsivi
quelle
0

Dies kann ein IPv6-Problem sein (der Host veröffentlicht eine IPv6-AAAA-Adresse und der Host des Benutzers glaubt, dass sie für IPv6 konfiguriert ist, aber tatsächlich nicht richtig verbunden ist). Dies kann auch ein Netzwerk-MTU-Problem sein, ein Firewall-Block, oder der Zielhost veröffentlicht möglicherweise verschiedene IP-Adressen (zufällig oder basierend auf dem Herkunftsland), die nicht alle erreichbar sind. Oder ähnliche Netzwerkprobleme.

Sie können nicht viel tun, außer ein Zeitlimit festzulegen und gute Fehlermeldungen hinzuzufügen (insbesondere das Drucken der aufgelösten Adresse des Hosts). Wenn Sie es robuster machen möchten, fügen Sie einen Wiederholungsversuch hinzu, versuchen Sie alle Adressen parallel und untersuchen Sie auch das Caching der Namensauflösung (positiv und negativ) auf der Java-Plattform.

eckes
quelle
0

Der Grund, warum mir dies passiert ist, war, dass ein Remote-Server nur eine bestimmte IP-Adresse zuließ, aber keine eigene. Ich habe versucht, die Bilder von den URLs des Servers zu rendern. Alles wurde einfach angehalten und der Timeout-Fehler angezeigt, den Sie hatten hätten...

Stellen Sie sicher, dass entweder der Server seine eigene IP zulässt oder dass Sie Dinge von einer tatsächlich vorhandenen Remote-URL rendern.

Damir Olejar
quelle
0

Warum sollte eine Ausnahme "java.net.ConnectException: Zeitüberschreitung der Verbindung" auftreten, wenn die URL aktiv ist?

Weil die URLConnection (HttpURLConnection / HttpsURLConnection) fehlerhaft ist. Sie können hier und hier darüber lesen . Unsere Lösung bestand aus zwei Dingen:

a) Stellen Sie die ContentLength über ein setFixedLengthStreamingMode

b) Fangen Sie eine TimeoutException ab und versuchen Sie es erneut, wenn sie fehlgeschlagen ist.

Lonzak
quelle