2016-04-22 63 views
0

下面是jstack的输出,看线程,nid = 0x771d(30493)。几个小时前开始的。httpclient.execute中HttpClientConnectionOperator.connect时忽略Socket读取超时

"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中)。

+0

该错误描述不正确。它的标题应该是'* read * timeout ignored'。 – EJP

+0

我正面临与4.5.2相同的问题 – Arya

+1

@RadLexus好的,完成了 –

回答

1

我找到了一个解决方案,将httpclient更新到4.3.6,问题就解决了。 这是apache JIRA。 更改后的代码是here

0

我不确定这是HTTPClient中的错误吗?

不是。任何这样的'bug'都会驻留在JVM中,而不是JSSE中,当然不在HTTPClient中。

如果是,那么哪个部件代码会造成这个问题?

无。往上看。

为什么线程处于RUNNABLE状态,并且CPU时间不增加?

正在运行的Java线程意味着它不会被Java中的任何东西阻碍,例如监视器或其他线程。这并不意味着它不会被操作系统的观点阻止,例如在阻塞阅读中,正如这里的情况一样。

在我看来,这是因为IO不能完成,所以不能发生CPU中断,但为什么状态不是SUSPEND。

no such state作为Thread.State.SUSPEND