如何防止在 Java 中挂起 SocketInputStream.socketRead0? [英] How to prevent hangs on SocketInputStream.socketRead0 in Java?
问题描述
使用不同的 Java 库执行数百万个 HTTP 请求让我的线程挂了:
Performing millions of HTTP requests with different Java libraries gives me threads hanged on:
java.net.SocketInputStream.socketRead0()
哪个是native
函数.
我尝试设置 Apche Http Client 和 RequestConfig
以在(我希望)所有可能的事情上超时,但仍然我(可能是无限)挂在 socketRead0代码>.如何摆脱它们?
I tried to set up Apche Http Client and RequestConfig
to have timeouts on (I hope) everythig that is possible but still, I have (probably infinite) hangs on socketRead0
. How to get rid of them?
挂起比率约为每 10000 个请求(针对 10000 个不同的主机)约 1 次,并且它可能会持续永远(我已确认挂起的线程在 10 小时后仍然有效).
Hung ratio is about ~1 per 10000 requests (to 10000 different hosts) and it can last probably forever (I've confirmed thread hung as still valid after 10 hours).
Windows 7 上的 JDK 1.8.
JDK 1.8 on 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);
注意:实际上我有一些技巧" - 我可以在其他 Thread
中安排 .getConnectionManager().shutdown()
并取消 Future
如果请求正确完成,但它已被弃用,并且它会杀死整个 HttpClient
,而不仅仅是单个请求.
Note: Actually I have some "trick" - I can schedule .getConnectionManager().shutdown()
in other Thread
with cancellation of Future
if request finished properly, but it is depracated and also it kills whole HttpClient
, not only that single request.
推荐答案
对于 Apache HTTP 客户端(阻塞),我发现最好的解决方案是 getConnectionManager().并关闭它.
For Apache HTTP Client (blocking) I found best solution is to getConnectionManager(). and shutdown it.
所以在高可靠性解决方案中,我只是在其他线程中安排关闭,如果请求未完成,我将从其他线程关闭
So in high-reliability solution I just schedule shutdown in other thread and in case request does not complete I'm shutting in down from other thread
这篇关于如何防止在 Java 中挂起 SocketInputStream.socketRead0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!