Mengapa pengecualian "java.net.ConnectException: Waktu koneksi habis" terjadi saat URL habis?

86

Saya mendapatkan ConnectException: Connection timed outdengan beberapa frekuensi dari kode saya. URL yang saya coba cari sudah habis. Kode yang sama berfungsi untuk beberapa pengguna, tetapi tidak untuk yang lain. Sepertinya begitu satu pengguna mulai mendapatkan pengecualian ini, mereka terus mendapatkan pengecualian.

Berikut adalah jejak tumpukan:

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)

Ini potongan dari kode saya:

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
sumber
7
Harap tandai satu jawaban sebagai diterima jika Anda telah memecahkan masalah Anda :)
Tobias

Jawaban:

84

Waktu tunggu koneksi (dengan asumsi jaringan lokal dan beberapa mesin klien) biasanya dihasilkan dari

a) sejenis firewall dalam perjalanan yang hanya memakan paket tanpa memberi tahu pengirim hal-hal seperti "Tidak Ada Rute ke host"

b) kehilangan paket karena konfigurasi jaringan yang salah atau kelebihan jalur

c) terlalu banyak permintaan yang membebani server

d) sejumlah kecil utas / proses yang tersedia secara bersamaan di server yang mengarah ke semuanya diambil. Hal ini terjadi terutama dengan permintaan yang membutuhkan waktu lama untuk dijalankan dan mungkin digabungkan dengan c).

Semoga ini membantu.

Gelisah
sumber
Apa yang membantu saya untuk men-debug masalah ini adalah melakukan ping ke server yang saya minta. Saya menemukan URL diselesaikan ke IP publik, bukan IP pribadi yang saya inginkan. Pemetaan baru di file / etc / hosts diizinkan untuk memperbaiki masalah. Saya menambahkan komentar kalau-kalau ada orang lain yang menghadapi masalah serupa.
Bouramas
32

Jika URL berfungsi dengan baik di browser web pada mesin yang sama, mungkin kode Java tidak menggunakan proxy HTTP yang digunakan browser untuk menyambungkan ke URL.

Alexander
sumber
6

Pesan kesalahan mengatakan semuanya: waktu koneksi Anda habis. Ini berarti permintaan Anda tidak mendapat tanggapan dalam beberapa jangka waktu (default). Alasan tidak ada tanggapan yang diterima kemungkinan besar adalah salah satu dari:

a) IP / domain atau port salah

b) IP / domain atau port (mis. layanan) sedang down

c) IP / domain membutuhkan waktu lebih lama dari waktu tunggu default Anda untuk merespons

d) Anda memiliki firewall yang memblokir permintaan atau tanggapan pada port apa pun yang Anda gunakan

e) Anda memiliki firewall yang memblokir permintaan ke host tersebut

f) Akses internet Anda tidak aktif

g) Live-server Anda sedang down, misalnya dalam kasus "rest-API call".

Perhatikan bahwa firewall dan port atau pemblokiran IP mungkin dilakukan oleh ISP Anda

M Hamza Javed
sumber
4

Saya akan merekomendasikan menaikkan waktu tunggu koneksi sebelum mendapatkan aliran keluaran, seperti ini:

urlConnection.setConnectTimeout(1000);

Di mana 1000 dalam milidetik (1000 milidetik = 1 detik).

Powerlord
sumber
21
Itu tidak menaikkannya, itu menurunkannya, secara drastis. Standarnya sekitar satu menit, dan Anda tidak dapat meningkatkannya, Anda hanya dapat menurunkannya.
pengguna207421
3
  • coba lakukan Telnet untuk melihat masalah firewall
  • melakukan tracert/ tracerouteuntuk menemukan jumlah lompatan
kebiruan
sumber
traceroute ke mana?
pesawat
jelas, untuk ip apa pun Anda mendapatkan kesalahan.
John Lord
3

Saya memecahkan masalah saya dengan:

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

atau http.proxyHost...

NikNik
sumber
1

Ini bisa menjadi masalah IPv6 (host menerbitkan IPv6 AAAA-Address dan host pengguna mengira itu dikonfigurasi untuk IPv6 tetapi sebenarnya tidak terhubung dengan benar). Ini juga bisa menjadi masalah MTU jaringan, blok firewall, atau host target mungkin menerbitkan alamat IP yang berbeda (secara acak atau berdasarkan negara pembuatnya) yang tidak semuanya dapat dijangkau. Atau masalah jaringan yang serupa.

Anda tidak dapat berbuat banyak selain mengatur batas waktu dan menambahkan pesan kesalahan yang baik (terutama mencetak alamat host yang diselesaikan). Jika Anda ingin membuatnya lebih kuat, tambahkan percobaan ulang, percobaan paralel semua alamat dan juga lihat cache resolusi nama (positif dan negatif) pada platform Java.

eckes
sumber
1

Mengapa pengecualian "java.net.ConnectException: Waktu koneksi habis" terjadi saat URL habis?

Karena URLConnection (HttpURLConnection / HttpsURLConnection) tidak menentu. Anda dapat membaca tentang ini di sini dan di sini . Solusi kami adalah dua hal:

a) mengatur ContentLength melalui setFixedLengthStreamingMode

b) menangkap TimeoutException dan coba lagi jika gagal.

Lonzak
sumber
0

Ada kemungkinan bahwa IP / host Anda diblokir oleh host jarak jauh, terutama jika menurutnya Anda terlalu memaksakannya.

larsivi.dll
sumber
0

Alasan mengapa ini terjadi pada saya adalah bahwa server jarak jauh hanya mengizinkan alamat IP tertentu tetapi tidak miliknya, dan saya mencoba untuk membuat gambar dari URL server ... jadi semuanya akan berhenti, menampilkan kesalahan batas waktu yang Anda punya ...

Pastikan bahwa server mengizinkan IP-nya sendiri, atau Anda merender sesuatu dari beberapa URL jarak jauh yang benar-benar ada.

Damir Olejar
sumber