java - 在 httpclient.execute 中的 HttpClientConnectionOperator.connect 时忽略套接字读取超时

标签 java multithreading sockets ssl httpclient

下面是 jstack 的输出,观察线程,nid=0x771d (30493)。几个小时前开始的。

"taskScheduler-6" prio=10 tid=0x00007f4479e07800 nid=0x771d runnable [0x00007f446e63a000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:152)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
    at sun.security.ssl.InputRecord.readV3Record(InputRecord.java:554)
    at sun.security.ssl.InputRecord.read(InputRecord.java:509)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:934)
    - locked <0x00000007601abdf0> (a java.lang.Object)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
    - locked <0x00000007601abea0> (a java.lang.Object)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory
.java:275)
    at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:
254)
    at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:1
23)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionMa
nager.java:318)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)

    ........ // other call stack of custom codes

并且线程的CPU时间始终不变,不变:(由top -Hp pid产生)

  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
30493 root      20   0 3832m 1.0g  11m S   0.0  2.2   0:01.20 java

Java代码如下:

    RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(so_timeout_milliseconds)
                        .setConnectTimeout(so_timeout_milliseconds).setSocketTimeout(so_timeout_milliseconds).build();  // so_timeout_milliseconds = 6000
    do {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpGet httpget = new HttpGet(url);
            httpget.setConfig(config);
            if (headers != null) {
                for (Header header : headers) {
                    httpget.addHeader(header);
                }
            }

            CloseableHttpResponse response = httpclient.execute(httpget); // see jstack output above
            try {
                StatusLine statusLine = response.getStatusLine();
                if (statusLine.getStatusCode() == HttpStatus.SC_OK) {
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                        InputStream instream = entity.getContent();
                        try {
                            return IOUtils.isToString(instream);
                        } catch (IOException ex) {
                            throw ex;
                        } finally {
                            instream.close();
                        }
                    }
                }
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    } while (--try_times > 0);

HttpClient 版本:

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.3.5</version>
    </dependency>
  1. 我不确定这是不是 HTTPClient 中的错误?如果是,是什么零件代码导致了这个问题?
  2. 为什么线程是RUNNABLE状态,CPU时间不增加?

在我看来,这是因为IO无法完成,所以不会发生CPU中断,但为什么状态不是SUSPEND。(我的意思是WAITING在 Java 中)。

最佳答案

找到解决方法,将httpclient升级到4.3.6,问题解决。 这是 apache JIRA . 更改后的代码是 here .

关于java - 在 httpclient.execute 中的 HttpClientConnectionOperator.connect 时忽略套接字读取超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36791569/

相关文章:

java - 连接被 peer : socket write error. 重置我的 Java 代码有什么问题

java - 如何在 eclipse 中添加来自 XChart 的 javadocs

java Android - 以编程方式处理图像缩放/裁剪

java - 在java中使用vigenere密码加密字节数组

Java:Comparable<List<T 扩展 Comparable<T>>>

ios - While 循环和触摸事件 Swift iOS

multithreading - 使用 webworker-threads 在 Node.js 中并发

C++ 在线程中传递 std::function 并使用自定义对象作为参数

用于 TCP 消息传递的 .NET 项目

javascript - 使用 Ratchet 网络套接字时如何定义路由?