Мы используем HttpURLConnection API, чтобы часто вызывать REST API для одного и того же провайдера (тип агрегации). Мы хотим, чтобы пул из 5 соединений всегда был открыт для хоста провайдера (всегда один и тот же IP-адрес).
Какое правильное решение? Вот что мы попробовали:
System.setProperty("http.maxConnections", 5); // set globally only once
...
// everytime we need a connection, we use the following
HttpURLConnection conn = (HttpURLConnection) (new URL(url)).openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setDoOutput(false);
conn.setUseCaches(true);
...
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
...
На этом этапе мы читаем входной поток, пока BufferedReader больше не возвращает байтов. Что мы делаем после этого, если хотим повторно использовать базовое соединение с провайдером? У нас сложилось впечатление, что если входной поток полностью прочитан, соединение затем добавляется обратно в пул.
Таким образом, он работал несколько недель, но сегодня он перестал работать, выдав это исключение: java.net.SocketException: Too many open files
Мы нашли множество сокетов в состоянии CLOSE_WAIT следующим образом (запустив lsof
):
java 1814 root 97u IPv6 844702 TCP colinux:58517->123.123.254.205:www (CLOSE_WAIT)
Не будет ли conn.getInputStream (). Close () или conn.disconnect () полностью закрыть соединение и удалить его из пула?