Проблемы с использованием библиотеки Apache `httpclient` для создания тысяч подключений к локальному хосту.JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Проблемы с использованием библиотеки Apache `httpclient` для создания тысяч подключений к локальному хосту.

Сообщение Anonymous »

Я пытаюсь написать тестовый пример для веб-сервера, который принимает запросы POST с небольшим телом JSON. Я пытаюсь имитировать многие сотни запросов в секунду. Я использую PoolingHttpClientConnectionManager, чтобы попытаться минимизировать рабочую нагрузку на саму тестовую программу, поскольку мне интересно посмотреть, как сервер реагирует на такого рода нагрузку. Я запускаю тест на той же машине, что и сервер, поэтому подключаюсь к http://localhost:8080/example
Фактическая тестовая программа довольно длинная, поскольку она касается с генерацией правдоподобных данных, но основная проблема, с которой у меня возникают проблемы, заключается в следующем:

Код: Выделить всё

    //
// http connection pool is set up like this:
//
httpPool = new PoolingHttpClientConnectionManager();
httpPool.setMaxTotal(100);
httpPool.setDefaultMaxPerRoute(100);

//
// then this is called frequently:
//
private void post(String url, String json) throws IOException {
exec.submit(() -> {
try  {
CloseableHttpClient client = HttpClients.custom().setConnectionManager(httpPool).build();
HttpPost post = new HttpPost(url);
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
post.setEntity(entity);

try (CloseableHttpResponse response = client.execute(post)) {
//log(url + ": " + EntityUtils.toString(response.getEntity()));
}
} catch (Exception e) {
e.printStackTrace();
}
});
}
В настоящее время он работает нормально со скоростью около 150 запросов в секунду. Примерно через минуту он умирает, и каждый запрос выдает это исключение:

Код: Выделить всё

org.apache.hc.client5.http.HttpHostConnectException: Connect to http://localhost:8080 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: getsockopt
at java.base/sun.nio.ch.Net.pollConnect(Native Method)
at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:682)
at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:542)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:592)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:751)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.socket.PlainConnectionSocketFactory$1.run(PlainConnectionSocketFactory.java:87)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:571)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:84)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.io.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:148)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:407)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.classic.InternalExecRuntime.connectEndpoint(InternalExecRuntime.java:168)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.classic.InternalExecRuntime.connectEndpoint(InternalExecRuntime.java:178)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:136)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:165)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.classic.ExecChainElement$1.proceed(ExecChainElement.java:57)
at org.apache.httpcomponents.client5.httpclient5@5.1/org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:96)
( this goes on...  )
На сервере все в порядке, он просто перестает видеть новые соединения (он построен на основе Undertow, если это актуально)
Что интересно, если я немедленно перезапущу тест, он почти сразу же завершится с этой ошибкой. Если я подожду несколько минут, он снова будет работать около минуты и обработает где-то около 10 тысяч запросов, прежде чем он упадет. Это заставляет меня думать, что у него заканчивается какой-то ресурс уровня ОС, пополнение которого требует времени? Типа дескрипторов или чего-то еще.
У кого-нибудь есть идеи?
РЕДАКТИРОВАТЬ: стоит отметить, что если я убью серверный процесс и быстро перезапущу его, то я все равно см. эту проблему, которая заставляет меня поверить, что это не какая-то ошибка, накапливающаяся в коде на стороне сервера

Подробнее здесь: https://stackoverflow.com/questions/790 ... -localhost
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»