首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当HttpClientConnectionOperator.connect在httpclient.execute中时忽略套接字读取超时

当HttpClientConnectionOperator.connect在httpclient.execute中时忽略套接字读取超时
EN

Stack Overflow用户
提问于 2016-04-22 10:40:51
回答 2查看 963关注 0票数 0

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

代码语言:javascript
复制
"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生成)

代码语言:javascript
复制
  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代码:

代码语言:javascript
复制
    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版本:

代码语言:javascript
复制
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.3.5</version>
    </dependency>
  1. 我不确定这是HTTPClient中的一个bug吗?如果是,是哪一部分代码造成了这个问题?
  2. 为什么线程是RUNNABLE状态,而CPU时间没有增加?

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-26 01:13:45

我找到了一个解决方案,将httpclient更新为4.3.6,问题就解决了。我是阿帕奇JIRA。修改后的代码为这里

票数 1
EN

Stack Overflow用户

发布于 2016-04-22 10:46:58

我不确定这是HTTPClient中的一个bug吗?

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

如果是,是哪一部分代码造成了这个问题?

没有。请参见上面的。

为什么线程是可运行状态,而CPU时间没有增加?

可运行的Java线程意味着它不会被Java中的任何东西所阻碍,比如监视器或其他线程。从操作系统的角度来看,这并不意味着is没有被阻止,例如在阻塞读取中,就像这里的情况一样。

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

没有这样的状态作为Thread.State.SUSPEND

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36791569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档