在項目期初是用HttpConnection,近期爲了用應對大促問題,大家決定將請求外部地圖接口改爲httpclient連接池。期初是朝着httpclient4.X準備的,結果在開發過程中,發現項目中引入的是httpClient3.2。多方找資料,發現3.X的資料已經相當少,特記錄一下。
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
/**
* 單例連接池
*
*/
public class HttpClientPool {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientPool.class);
private static volatile HttpClientPool pool;
private MultiThreadedHttpConnectionManager connectionManager;
private HttpClientPool(){
connectionManager = new MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams params = new HttpConnectionManagerParams();//連接池屬性實例
params.setDefaultMaxConnectionsPerHost(100);//每個網址最大連接數
params.setMaxTotalConnections(100);//最大連接數
params.setConnectionTimeout(1000);//連接超時時間
params.setSoTimeout(2000);//獲取數據超時時間
connectionManager.setParams(params);
}
public static HttpClientPool getInstance(){
if(null == pool){
LOGGER.info("外層判斷實例不存在,進行鎖定,鎖定線程{}",Thread.currentThread().getName());
synchronized (HttpClientPool.class){
if(null == pool){
LOGGER.info("內層判斷實例不存在,進行創建線程池,創建線程{}",Thread.currentThread().getName());
pool = new HttpClientPool();
}
}
}
return pool;
}
/**
* 執行get方法,並將返回信息以字符串返回-不允許有留或文件操作
* @param url
* @return
* @throws IOException
*/
public String exeGetMethod(String url) {
LOGGER.info("通過HttpClient請求路徑:{}",url);
GetMethod getMethod = null;
try {
HttpClient client = new HttpClient(this.connectionManager);//創建客戶端,並交由連接池管理
getMethod = new GetMethod(url);
int statusCode = client.executeMethod(getMethod);
if(200 == statusCode){
return getMethod.getResponseBodyAsString();
}else {
LOGGER.info("獲取網絡信息失敗,url:{},返回碼:{}",url,statusCode);
throw new RuntimeException("獲取網絡信息失敗,url:" + url + ",返回碼:" + statusCode);
}
} catch (Exception e){
LOGGER.error("調用httpclient異常:",e);
throw new RuntimeException("調用HttpClient異常!");
} finally {
if(null != getMethod){
getMethod.releaseConnection();//釋放連接
}
}
}
}
HttpClient 3.X連接池注意事項:
1. 創建MultiThreadedHttpConnectionManager對象
2. client屬性設置通過HttpConnectionManagerParams對象,如最大連接數、超時時間等。
3. 創建HttpClient對象需要傳入創建MultiThreadedHttpConnectionManager對象,這樣創建的client對象是交由連接池管理的
4. 調用結束後,需要將連接釋放。getMethod.releaseConnection();