2016-04-22 5 views
0

以下はjstackの出力です。スレッドnid = 0x771d(30493)を見てください。数時間前に始まった。httpclient.executeでHttpClientConnectionOperator.connectを実行すると、ソケットの読み取りタイムアウトが無視される

"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時間が増えないのですか?私の意見で

それはCPU割り込みを発生することができないので、この理由は、IOの完了できませんが、なぜ状態がSUSPENDではありません。(私はJavaでWAITINGを意味します)。

+0

このバグは間違って記述されています。 '* read * timeout ignored。'というタイトルにする必要があります。 – EJP

+0

私は同じ問題に直面しています4.5.2 – Arya

+1

@RadLexus –

答えて

1

解決策が見つかりました。httpclientを4.3.6にアップデートして、問題を解決しました。 です。 変更されたコードはhereです。

0

これはHTTPClientのバグですか?

いいえこのような「バグ」は、JSSEではなく、確かにHTTPClientには存在しません。

この場合、どのような部品コードでこの問題が発生しますか?

なし。上記を参照。

スレッドがRUNNABLEステータスで、CPU時間が増加しないのはなぜですか?

JavaスレッドがRUNNABLEであるということは、Javaのモニタやスレッドなどの何かによって妨げられていないことを意味します。これは、オペレーティングシステムの観点からブロックされていないことを意味するものではありません。ここでの場合のように、ブロッキング読み出しで私の意見で

、これはIOの完了できませんので、それはCPU割り込みを発生することはできませんが、ステータスがSUSPENDない理由。

としてno such stateがあります。

関連する問題