小编Fab*_*nte的帖子

如何防止Java中的SocketInputStream.socketRead0挂起?

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

java.net.SocketInputStream.socketRead0()

哪个是native功能.

我试图设置Apche Http Client,并且RequestConfig(我希望)有一些可能的超时,但我仍然(可能无限)挂起socketRead0.如何摆脱它们?

挂起比率约为每10000个请求约1个(到10000个不同的主机)并且它可能永远持续(我已确认线程挂起仍然有效,10小时后仍然有效).

Windows 7上的JDK 1.8.

我的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();
Run Code Online (Sandbox Code Playgroud)

我的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);
Run Code Online (Sandbox Code Playgroud)

OpenJDK socketRead0源码

注意:实际上我有一些"技巧" - 我可以.getConnectionManager().shutdown()在其他方面安排Thread取消,Future如果请求已正确完成,但它被删除,并且它也杀死了整个HttpClient,而不仅仅是单个请求.

java sockets timeout http apache-httpclient-4.x

51
推荐指数
5
解决办法
3万
查看次数

标签 统计

apache-httpclient-4.x ×1

http ×1

java ×1

sockets ×1

timeout ×1