如何防止Java中的SocketInputStream.socketRead0挂起? [英] How to prevent hangs on SocketInputStream.socketRead0 in Java?

查看:2513
本文介绍了如何防止Java中的SocketInputStream.socketRead0挂起?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用不同的Java库执行数百万个HTTP请求会让我挂起线程:

Performing millions of HTTP requests with different Java libraries gives me threads hanged on:

java.net.SocketInputStream.socketRead0()

哪个原生功能。

我尝试设置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 factory:

My HttpClient factory:

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

OpenJDK socketRead0 source

OpenJDK socketRead0 source

注意:实际上我有一些技巧 - 我可以在其他<$ c中安排 .getConnectionManager()。shutdown() $ c>线程取消 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 Client(阻塞)我发现最好的解决方案是到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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆