2016-04-22 62 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