Как предотвратить зависания на SocketInputStream.socketRead0 в Java?
Выполнение миллионов HTTP-запросов с различными библиотеками Java приводит к зависанию потоков:
java.net.SocketInputStream.socketRead0()
Которыйnative
функция.
Я пытался настроить Apche Http Client иRequestConfig
иметь тайм-ауты (я надеюсь) на все, что возможно, но все же,У меня (наверное бесконечно) висит наsocketRead0
, Как от них избавиться?
Отношение зависания составляет около ~ 1 на 10000 запросов (к 10000 различным хостам), и оно может длиться, вероятно, вечно (я подтвердил, что поток завис как действующий через 10 часов).
JDK 1.8 на Windows 7.
мойHttpClient
завод:
SocketConfig socketConfig = SocketConfig.custom()
.setSoKeepAlive(false)
.setSoLinger(1)
.setSoReuseAddress(true)
.setSoTimeout(5000)
.setTcpNoDelay(true).build();
HttpClientBuilder builder = HttpClientBuilder.create();
builder.disableAutomaticRetries();
builder.disableContentCompression();
builder.disableCookieManagement();
builder.disableRedirectHandling();
builder.setConnectionReuseStrategy(new NoConnectionReuseStrategy());
builder.setDefaultSocketConfig(socketConfig);
return HttpClientBuilder.create().build();
мойRequestConfig
завод:
HttpGet request = new HttpGet(url);
RequestConfig config = RequestConfig.custom()
.setCircularRedirectsAllowed(false)
.setConnectionRequestTimeout(8000)
.setConnectTimeout(4000)
.setMaxRedirects(1)
.setRedirectsEnabled(true)
.setSocketTimeout(5000)
.setStaleConnectionCheckEnabled(true).build();
request.setConfig(config);
return new HttpGet(url);
Примечание: на самом деле у меня есть "трюк" - я могу запланировать.getConnectionManager().shutdown()
в другихThread
с отменойFuture
если запрос завершен правильно, но он испорчен, а также убивает весьHttpClient
не только этот единственный запрос.