4

我从 HttpClient 得到奇怪的行为,参数 CoreConnectionPNames.CONNECTION_TIMEOUT 设置为 1。我希望 HttpGet 请求会失败,抛出连接超时异常,但它们是成功的。这似乎不合理,因为它实际上意味着 TCP 握手在不到 1 毫秒的时间内完成。

在 pom.xml 中可以看到我正在使用的 httpclient 版本是

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.0.1</version>
        <type>jar</type>
    </dependency>

这是代码:

import java.io.IOException;
import java.util.Random;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

public class TestNodeAliveness {
    private static Logger log = Logger.getLogger(TestNodeAliveness.class);

    public static boolean nodeBIT(String elasticIP) throws ClientProtocolException, IOException {
        try {
            HttpClient client = new DefaultHttpClient();

            // The time it takes to open TCP connection.
            client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 1);

            // Timeout when server does not send data.
            client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000);

            // Some tuning that is not required for bit tests.
            client.getParams().setParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false);
            client.getParams().setParameter(CoreConnectionPNames.TCP_NODELAY, true);


            HttpUriRequest request = new HttpGet("http://" + elasticIP);
            HttpResponse response = client.execute(request);

            HttpEntity entity = response.getEntity();
            if(entity == null) { 
                return false;
            } else {
                System.out.println(EntityUtils.toString(entity));
            }

            // Close just in case.
            request.abort();

        } catch (Throwable e) {
            log.warn("BIT Test failed for " + elasticIP);
            e.printStackTrace();

            return false;
        }

        return true;
    }


    public static void main(String[] args) throws ClientProtocolException, IOException {
        nodeBIT("google.com?cant_cache_this=" + (new Random()).nextInt());
    }
}

这怎么可能?谢谢你。

4

2 回答 2

5

在我使用过的所有 JVM 中,有效的超时粒度约为 15-30 毫秒。即使超时设置为 1 个套接字 I/O 并且连接请求通常会成功,如果它们花费的时间少于 15-30 毫秒。

于 2010-06-09T21:51:27.907 回答
1

如果您设置 HttpGet 的超时时间,而不是 HttpClient,它似乎工作得更好。

    HttpGet httpget = new HttpGet("http://www.apache.org/");

    RequestConfig Default = RequestConfig.DEFAULT;

    RequestConfig requestConfig = RequestConfig.copy(Default)
            .setSocketTimeout(5000)
            .setConnectTimeout(5000)
            .setConnectionRequestTimeout(5000)
            .build();
    httpget.setConfig(requestConfig);
于 2014-12-10T09:38:35.997 回答