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

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

问题描述

使用不同的 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);

OpenJDK socketRead0 源码

注意:实际上我有一些技巧" - 我可以在其他 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屋!

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