2010-06-08 85 views
3

我得到奇怪的行爲從HttpClient的參數CoreConnectionPNames.CONNECTION_TIMEOUT設置爲1. 我期望HttpGet請求會失敗,拋出連接超時異常,但他們是成功的。這似乎不合理,因爲它實際上意味着TCP握手在1毫秒內完成。Apache HttpClient CoreConnectionPNames.CONNECTION_TIMEOUT什麼都不做?

我使用HttpClient的版本可以在這個pom.xml中可以看出是

<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

我所使用的所有JVM中超時的有效粒度大約爲15-30ms。即使超時設置爲1套接字I/O,並且連接請求通常會在小於15-30ms的時間內成功完成。

+2

好的,你如何有效地設置一個超時時間,如果你在5秒後沒有收到來自服務器的響應,則會拋出異常? – jonney 2010-12-16 09:37:50

0

如果你設置了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);