問題html
以前使用httpclient請求數據java
源碼方法:併發
public static String doHttp(HttpMethod result, int timeout, String charset) { HttpClient client = new HttpClient(); try { HttpConnectionManagerParams managerParams = client.getHttpConnectionManager().getParams(); managerParams.setConnectionTimeout(timeout); client.executeMethod(result); InputStream resStream = result.getResponseBodyAsStream(); BufferedReader br = new BufferedReader(new InputStreamReader(resStream, charset)); StringBuffer resBuffer = new StringBuffer(); String resTemp = ""; while ((resTemp = br.readLine()) != null) { resBuffer.append(resTemp); } return resBuffer.toString(); } catch (HttpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { result.releaseConnection(); } return null; }
發現其中在app
client.executeMethod(result);
一隻會卡在這裏不出來,究其緣由在於對post
managerParams.setConnectionTimeout(timeout);//爲鏈接超時
這裏使用的是鏈接超時,而我這裏還缺乏了一個數據超時,不然會一直等待數據返回因此在下面在添加請求數據超時代碼。測試
如下爲完整的代碼:(其中紅色部分爲此次的主角)spa
public static String doHttp(HttpMethod result, int timeout, String charset) { HttpClient client = new HttpClient(); try { HttpConnectionManagerParams managerParams = client.getHttpConnectionManager().getParams(); managerParams.setConnectionTimeout(timeout); managerParams.setSoTimeout(timeout);//等待結果超時 client.executeMethod(result); InputStream resStream = result.getResponseBodyAsStream(); BufferedReader br = new BufferedReader(new InputStreamReader(resStream, charset)); StringBuffer resBuffer = new StringBuffer(); String resTemp = ""; while ((resTemp = br.readLine()) != null) { resBuffer.append(resTemp); } return resBuffer.toString(); } catch (HttpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { result.releaseConnection(); } return null; }
看介紹code
本文介紹來自http://jinnianshilongnian.iteye.com/blog/2089792htm
HttpParams params = new BasicHttpParams(); //設置鏈接超時時間 Integer CONNECTION_TIMEOUT = 2 * 1000; //設置請求超時2秒鐘 根據業務調整 Integer SO_TIMEOUT = 2 * 1000; //設置等待數據超時時間2秒鐘 根據業務調整 //定義了當從ClientConnectionManager中檢索ManagedClientConnection實例時使用的毫秒級的超時時間 //這個參數指望獲得一個java.lang.Long類型的值。若是這個參數沒有被設置,默認等於CONNECTION_TIMEOUT,所以必定要設置 Long CONN_MANAGER_TIMEOUT = 500L; //該值就是鏈接不夠用的時候等待超時時間,必定要設置,並且不能太大 () params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, CONNECTION_TIMEOUT); params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SO_TIMEOUT); params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, CONN_MANAGER_TIMEOUT); //在提交請求以前 測試鏈接是否可用 params.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, true); PoolingClientConnectionManager conMgr = new PoolingClientConnectionManager(); conMgr.setMaxTotal(200); //設置整個鏈接池最大鏈接數 根據本身的場景決定 //是路由的默認最大鏈接(該值默認爲2),限制數量實際使用DefaultMaxPerRoute並不是MaxTotal。 //設置太小沒法支持大併發(ConnectionPoolTimeoutException: Timeout waiting for connection from pool),路由是對maxTotal的細分。 conMgr.setDefaultMaxPerRoute(conMgr.getMaxTotal());//(目前只有一個路由,所以讓他等於最大值) //另外設置http client的重試次數,默認是3次;當前是禁用掉(若是項目量不到,這個默認便可) httpClient.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false));
此處解釋下MaxtTotal和DefaultMaxPerRoute的區別:blog
HttpConnectionManagerParams params = new HttpConnectionManagerParams(); params.setConnectionTimeout(2000); params.setSoTimeout(2000); // 最大鏈接數 params.setMaxTotalConnections(500); params.setDefaultMaxConnectionsPerHost(500); params.setStaleCheckingEnabled(true); connectionManager.setParams(params); HttpClientParams httpClientParams = new HttpClientParams(); // 設置httpClient的鏈接超時,對鏈接管理器設置的鏈接超時是無用的 httpClientParams.setConnectionManagerTimeout(5000); //等價於4.2.3中的CONN_MANAGER_TIMEOUT httpClient = new HttpClient(connectionManager); httpClient.setParams(httpClientParams); //另外設置http client的重試次數,默認是3次;當前是禁用掉(若是項目量不到,這個默認便可) httpClientParams.setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0, false));
參數相似 就很少解釋了;
另看一片轉載內容
HttpClient 4 和 HttpClient 3 設置超時
HttpClient 4:
鏈接超時:
httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,60000);
// 或者
HttpConnectionParams.setConnectionTimeout(params, 6000);
讀取超時:
httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,60000);
// 或者
HttpConnectionParams.setSoTimeout(params, 60000);
HttpClient 3:
鏈接超時:
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(60000);
讀取超時:
httpClient.getHttpConnectionManager().getParams().setSoTimeout(60000);