HttpClient超時設置詳解


來源於:https://blog.csdn.net/u011191463/article/details/78664896

 

HttpClient 4.3。HttpClient這貨和Lucene一樣,每個版本的API都變化很大,這有點讓人頭疼。就好比創建一個HttpClient對象吧,每一個版本的都不一樣,

3.X是這樣的

?
1
HttpClient httpClient= new DefaultHttpClient();

4.3是這樣的

?
1
CloseableHttpClient httpClient = HttpClients.createDefault();

當然,上面這些變化只不過是一些小變化,大家看看API大家就都會了。

我要講的是超時設置,HttpClient有三種超時設置,最近比較忙,沒時間具體歸納總結,以后再補上,我這里就講一些最簡單最易用的超時設置方法。

這是個3.X的超時設置方法

?
1
2
3
HttpClient client =  new HttpClient();
client.setConnectionTimeout( 30000 ); 
client.setTimeout( 30000 );
?
1
2
HttpClient httpClient=  new HttpClient(); 
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout( 5000 );

4.X版本的超時設置(4.3后已過時)

?
1
2
3
HttpClient httpClient= new DefaultHttpClient();
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 2000 ); //連接時間
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 2000 ); //數據傳輸時間

4.3版本超時設置

?
1
2
3
4
5
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet= new HttpGet( "http://www.baidu.com" );//HTTP Get請求(POST雷同)
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout( 2000 ).setConnectTimeout( 2000 ).build(); //設置請求和傳輸超時時間
httpGet.setConfig(requestConfig);
httpClient.execute(httpGet); //執行請求

BTW,4.3版本不設置超時的話,一旦服務器沒有響應,等待時間N久(>24小時)。

 

 

       HttpClient升級到4.5版本后,API有很多變化,HttpClient 4之后,API一直沒有太穩定,我感覺4.5版本抽象后,很多API應該快穩定了。

       使用HttpClient,一般都需要設置連接超時時間和獲取數據超時時間。這兩個參數很重要,目的是為了防止訪問其他http時,由於超時導致自己的應用受影響。

       4.5版本中,這兩個參數的設置都抽象到了RequestConfig中,由相應的Builder構建,具體的例子如下:

?
1
2
3
4
5
6
7
8
9
CloseableHttpClient httpclient = HttpClients.createDefault();  
HttpGet httpGet =  new  HttpGet( "http://stackoverflow.com/" );  
RequestConfig requestConfig = RequestConfig.custom()  
         .setConnectTimeout( 5000 ).setConnectionRequestTimeout( 1000 )  
         .setSocketTimeout( 5000 ).build();  
httpGet.setConfig(requestConfig);  
CloseableHttpResponse response = httpclient.execute(httpGet);  
System.out.println( "得到的結果:"  + response.getStatusLine()); //得到請求結果  
HttpEntity entity = response.getEntity(); //得到請求回來的數據

setConnectTimeout:設置連接超時時間,單位毫秒。

setConnectionRequestTimeout:設置從connect Manager(連接池)獲取Connection 超時時間,單位毫秒。這個屬性是新加的屬性,因為目前版本是可以共享連接池的。

setSocketTimeout:請求獲取數據的超時時間(即響應時間),單位毫秒。 如果訪問一個接口,多少時間內無法返回數據,就直接放棄此次調用。

 

 

 

HttpClient內部有三個超時時間設置:連接池獲取可用連接超時,連接超時,讀取數據超時

先看以下HttpClient的初始化代碼:

 

[java]  view plain  copy
 
  1. RequestConfig requestConfig = RequestConfig.custom()  
  2.                     .setConnectionRequestTimeout(config.connReqTimeout)   //從連接池中獲取連接的超時時間  
  3.                             //與服務器連接超時時間:httpclient會創建一個異步線程用以創建socket連接,此處設置該socket的連接超時時間  
  4.                     .setConnectTimeout(config.connTimeout)  
  5.                     .setSocketTimeout(config.socketTimeout)               //socket讀數據超時時間:從服務器獲取響應數據的超時時間  
  6.                     .build();  
  7.             httpClient = HttpClientBuilder.create()  
  8.                     .setMaxConnTotal(config.maxConnTotal)                   //連接池中最大連接數  
  9.                             /** 
  10.                              * 分配給同一個route(路由)最大的並發連接數。 
  11.                              * route:運行環境機器 到 目標機器的一條線路。 
  12.                              * 舉例來說,我們使用HttpClient的實現來分別請求 www.baidu.com 的資源和 www.bing.com 的資源那么他就會產生兩個route。 
  13.                              */  
  14.                     .setMaxConnPerRoute(config.maxConnPerRoute)  
  15.                     .setDefaultRequestConfig(requestConfig)  
  16.                     .build();  



 

三個超時時間詳解:

1.從連接池中獲取可用連接超時

HttpClient中的要用連接時嘗試從連接池中獲取,若是在等待了一定的時間后還沒有獲取到可用連接(比如連接池中沒有空閑連接了)
則會拋出獲取連接超時異常。
 

2.連接目標超時connectionTimeout

 指的是連接目標url的連接超時時間,即客服端發送請求到與目標url建立起連接的最大時間。如果在該時間范圍內還沒有建立起連接,則就
拋出 connectionTimeOut異常。如測試的時候,將url改為一個不存在的url:“http://test.com” ,超時時間3000ms過后,系統報出異常:   
org.apache.commons.httpclient.ConnectTimeoutException:The host did not accept the connection within timeout of 3000 ms 
 

3.等待響應超時(讀取數據超時)socketTimeout 

   連接上一個url后,獲取response的返回等待時間 ,即在與目標url建立連接后,等待放回response的最大時間,在規定時間內沒有返回響應的話就拋出SocketTimeout。
   測試的時候的連接url為我本地開啟的一個url,http://localhost:8080/firstTest.htm?method=test,在我這個測試url里,當訪問到這個鏈接時,線程sleep一段時間,來模擬返回response超時。 

Java代碼  

1. @RequestMapping(params = "method=test")  

2. public String testMethod(ModelMap model) {      

3. try {      

4.     Thread.sleep(10000);      

5. } catch (InterruptedException e) {      

6.     // TODO Auto-generated catch block      

7.     e.printStackTrace();      

8. }      

9.       System.out.println("call testMethod method.");      

10.       model.addAttribute("name", "test method");      

11. return "test";      

12.   }  


   將讀取response返回超時時間設的時間比那個sleep時間短之后,運行程序給出異常:java.net.SocketTimeoutException:Read timed out 

 

 

參考:http://blog.csdn.net/waterCabin/article/details/50294787

          http://blog.csdn.net/zhongzh86/article/details/46348933

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM