Почему при запуске URL-адреса возникает исключение "java.net.ConnectException: Connection timed out"?

Я получаю ConnectException: Connection timed out с некоторой частотой из своего кода. URL, который я пытаюсь ударить, вверх. Один и тот же код работает для некоторых пользователей, но не для других. Кажется, что, как только один пользователь начинает получать это исключение, они продолжают получать исключение.

Вот трассировка стека:

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)

Вот фрагмент кода:

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);
}

Ответ 1

Таймауты соединений (при условии, что локальная сеть и несколько клиентских машин) обычно возникают из

a) какой-то брандмауэр на пути, который просто ест пакеты, не сообщая отправителю такие вещи, как "No Route to host"

b) потери пакетов из-за неправильной конфигурации сети или перегрузки строк

c) слишком много запросов на перегрузку сервера

d) небольшое количество одновременно доступных потоков/процессов на сервере, что приводит к их удалению. Это происходит особенно с запросами, которые занимают много времени для запуска и могут сочетаться с c).

Надеюсь, что это поможет.

Ответ 2

Если URL-адрес работает хорошо в веб-браузере на том же компьютере, возможно, код Java не использует прокси-сервер HTTP, используемый браузером для подключения к URL-адресу.

Ответ 3

Я бы рекомендовал увеличить время ожидания соединения до получения выходного потока, например:

urlConnection.setConnectTimeout(1000);

Где 1000 - в миллисекундах (1000 миллисекунд = 1 секунда).

Ответ 4

  • попробуйте сделать Telnet, чтобы увидеть проблему с брандмауэром.
  • выполнить tracert/traceroute, чтобы найти количество переходов

Ответ 5

В сообщении об ошибке говорится все: время ожидания подключения. Это означает, что ваш запрос не получил ответа в течение некоторого (по умолчанию) таймфрейма. Причины, по которым не было получено никакого ответа, вероятно, будут следующими:

a) IP/домен или порт неверны

b) IP/домен или порт (например, служба) опущены

c) IP/домен занимает больше времени, чем ваш тайм-аут по умолчанию, чтобы ответить

d) У вас есть брандмауэр, который блокирует запросы или ответы на любом порту, который вы используете

e) У вас есть брандмауэр, который блокирует запросы к этому конкретному хосту

f) Ваш доступ в Интернет недоступен

g) Ваш живой сервер не работает, то есть в случае вызова "rest-API".

Обратите внимание, что брандмауэры и блокировка портов или IP-адресов могут быть установлены вашим провайдером

Ответ 6

Это может быть проблема IPv6 (хост публикует адрес AAAA-IPv6, и хост-пользователи считают, что он настроен для IPv6, но на самом деле он неправильно подключен). Это также может быть проблема MTU сети, блок брандмауэра, или целевой хост может публиковать различные IP-адреса (случайно или на основе страны-источника), которые не все доступны. Или проблемы с similiar network.

Вы не можете сделать многое помимо установки тайм-аута и добавления хороших сообщений об ошибках (особенно при печати адреса разрешенных хостов). Если вы хотите сделать его более надежным, добавьте повторную попытку, параллельную попытку всех адресов, а также посмотрите на кеширование имен (положительное и отрицательное) на платформе Java.

Ответ 7

Существует вероятность того, что ваш IP/хост заблокирован удаленным хостом, особенно если он считает, что вы слишком сильно нажимаете на него.

Ответ 8

Причина, по которой это произошло со мной, заключалась в том, что удаленный сервер разрешал только определенный IP-адрес, но не свой, и я пытался отображать изображения с URL-адресов серверов... так что все просто остановилось, показывая таймаут ошибка, которую вы имели...

Убедитесь, что либо сервер разрешает собственный IP-адрес, либо что вы делаете вещи с какого-то удаленного URL-адреса, который действительно существует.

Ответ 9

Я решил свою проблему:

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

или http.proxyHost...