最近公司需要对地址进行清洗,挑选了百度的LBS平台的Geocoding API v2接口,量级在千万级别。为了达到较高的效率,优化了下httpclient(版本:
4.2.3)的get请求,具体的就是使用http的连接池,这样不需要每次get都需要3次握手,大大提高了并发能力,并且失败率降低了100倍,具体代码如下:
public class HttpRequest {
private static PoolingClientConnectionManager conMgr = null;
static {
HttpParams params = new BasicHttpParams() ;
Integer CONNECTION_TIMEOUT = 2 * 1000 ; // 设置请求超时 2 秒钟 根据业务调整
Integer SO_TIMEOUT = 2 * 1000 ; // 设置等待数据超时时间 2 秒钟 根据业务调整
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) ;
conMgr = new PoolingClientConnectionManager() ;
conMgr.setMaxTotal( 2000) ;
conMgr.setDefaultMaxPerRoute( conMgr.getMaxTotal()) ;
}
public static String get(String url , String param) {
DefaultHttpClient httpClient = new DefaultHttpClient( conMgr) ;
// httpClient.setParams(params);
httpClient.setHttpRequestRetryHandler( new DefaultHttpRequestRetryHandler( 0 , false)) ;
HttpResponse httpResponse = null;
// 发送 get 请求
try {
// 用 get 方法发送 http 请求
HttpGet get = new HttpGet(url + URLEncoder. encode(param , "UTF-8")) ;
// HttpGet get = new HttpGet(url + param);
// get.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
// get.setHeader("Accept-Encoding", "gzip, deflate, sdch");
// get.setHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4");
// get.setHeader("Cache-Control", "max-age=0");
// get.setHeader("Connection", "keep-alive");
// get.setHeader("Content-Type", "text/xml;charset=utf-8");
// get.setHeader("Cookie", "BDUSS=EZZa1RmTVZWU0NqZ2VuM1RNdVhuYjR4QTkzbTNaMGRrNXladmFidFRwZHZmQ1pZQVFBQUFBJCQAAAAAAAAAAAEAAABNtEoNcWlhbmppY2hlbmdhYmMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG~v~ldv7~5XO; BAIDUID=50970119FD0148A9DC0B168BC1DF574C:FG=1; PSTM=1476958371; BDRCVFR[nXyXJys849T]=mk3SLVN4HKm; BIDUPSID=D09F46D9DB5776482C08FA93075CE076; MCITY=-289%3A; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=5; H_PS_PSSID=1429_19036_18240_17949_21109_17001_20593_21377_21189_21372");
// get.setHeader("Host", "180.97.33.90");
// get.setHeader("Upgrade-Insecure-Requests", "1");
get.setHeader( "User-Agent" , "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36") ;
System. out.println( " 执行 get 请求 , uri: " + get.getURI()) ;
httpResponse = httpClient.execute(get) ;
// response 实体
HttpEntity entity = httpResponse.getEntity() ;
if ( null != entity) {
String response = EntityUtils. toString(entity) ;
int statusCode = httpResponse.getStatusLine().getStatusCode() ;
// System.out.println(" 响应状态码 :" + statusCode);
// System.out.println(" 响应内容 :" + response);
if (statusCode == HttpStatus. SC_OK) {
// 成功
return response ;
} else {
return null;
}
}
} catch (IOException e) {
e.printStackTrace() ;
System. out.println( "httpclient 请求失败 ") ;
return null;
} finally {
if (httpResponse != null) {
try {
EntityUtils. consume(httpResponse.getEntity()) ; // 会自动释放连接
} catch (IOException e) {
e.printStackTrace() ;
}
}
}
return null;
}
private static PoolingClientConnectionManager conMgr = null;
static {
HttpParams params = new BasicHttpParams() ;
Integer CONNECTION_TIMEOUT = 2 * 1000 ; // 设置请求超时 2 秒钟 根据业务调整
Integer SO_TIMEOUT = 2 * 1000 ; // 设置等待数据超时时间 2 秒钟 根据业务调整
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) ;
conMgr = new PoolingClientConnectionManager() ;
conMgr.setMaxTotal( 2000) ;
conMgr.setDefaultMaxPerRoute( conMgr.getMaxTotal()) ;
}
public static String get(String url , String param) {
DefaultHttpClient httpClient = new DefaultHttpClient( conMgr) ;
// httpClient.setParams(params);
httpClient.setHttpRequestRetryHandler( new DefaultHttpRequestRetryHandler( 0 , false)) ;
HttpResponse httpResponse = null;
// 发送 get 请求
try {
// 用 get 方法发送 http 请求
HttpGet get = new HttpGet(url + URLEncoder. encode(param , "UTF-8")) ;
// HttpGet get = new HttpGet(url + param);
// get.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
// get.setHeader("Accept-Encoding", "gzip, deflate, sdch");
// get.setHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4");
// get.setHeader("Cache-Control", "max-age=0");
// get.setHeader("Connection", "keep-alive");
// get.setHeader("Content-Type", "text/xml;charset=utf-8");
// get.setHeader("Cookie", "BDUSS=EZZa1RmTVZWU0NqZ2VuM1RNdVhuYjR4QTkzbTNaMGRrNXladmFidFRwZHZmQ1pZQVFBQUFBJCQAAAAAAAAAAAEAAABNtEoNcWlhbmppY2hlbmdhYmMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG~v~ldv7~5XO; BAIDUID=50970119FD0148A9DC0B168BC1DF574C:FG=1; PSTM=1476958371; BDRCVFR[nXyXJys849T]=mk3SLVN4HKm; BIDUPSID=D09F46D9DB5776482C08FA93075CE076; MCITY=-289%3A; BDRCVFR[feWj1Vr5u3D]=I67x6TjHwwYf0; PSINO=5; H_PS_PSSID=1429_19036_18240_17949_21109_17001_20593_21377_21189_21372");
// get.setHeader("Host", "180.97.33.90");
// get.setHeader("Upgrade-Insecure-Requests", "1");
get.setHeader( "User-Agent" , "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/51.0.2704.79 Chrome/51.0.2704.79 Safari/537.36") ;
System. out.println( " 执行 get 请求 , uri: " + get.getURI()) ;
httpResponse = httpClient.execute(get) ;
// response 实体
HttpEntity entity = httpResponse.getEntity() ;
if ( null != entity) {
String response = EntityUtils. toString(entity) ;
int statusCode = httpResponse.getStatusLine().getStatusCode() ;
// System.out.println(" 响应状态码 :" + statusCode);
// System.out.println(" 响应内容 :" + response);
if (statusCode == HttpStatus. SC_OK) {
// 成功
return response ;
} else {
return null;
}
}
} catch (IOException e) {
e.printStackTrace() ;
System. out.println( "httpclient 请求失败 ") ;
return null;
} finally {
if (httpResponse != null) {
try {
EntityUtils. consume(httpResponse.getEntity()) ; // 会自动释放连接
} catch (IOException e) {
e.printStackTrace() ;
}
}
}
return null;
}
}
具体调用的时候可以N个线程使用线程池进行调用
4.5.2最新版的使用(2017-01-03更新)
public class HttpRequest {
private static Logger LOGGER = LoggerFactory. getLogger(HttpRequest. class) ;
private static PoolingHttpClientConnectionManager cm = null;
static {
LayeredConnectionSocketFactory sslsf = null;
try {
sslsf = new SSLConnectionSocketFactory(SSLContext. getDefault()) ;
} catch (NoSuchAlgorithmException e) {
LOGGER.error( " 创建 SSL 连接失败 ") ;
}
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
.register( "https" , sslsf)
.register( "http" , new PlainConnectionSocketFactory())
.build() ;
cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry) ;
cm.setMaxTotal( 200) ;
cm.setDefaultMaxPerRoute( 20) ;
}
private static CloseableHttpClient getHttpClient() {
CloseableHttpClient httpClient = HttpClients. custom()
.setConnectionManager( cm)
.build() ;
return httpClient ;
}
public static String get(String url , String param) {
// 创建默认的 httpClient 实例
CloseableHttpClient httpClient = HttpRequest. getHttpClient() ;
CloseableHttpResponse httpResponse = null;
// 发送 get 请求
try {
// 用 get 方法发送 http 请求
HttpGet get = new HttpGet(url + URLEncoder. encode(param , "UTF-8")) ;
LOGGER.info( " 执行 get 请求 , uri: " + get.getURI()) ;
httpResponse = httpClient.execute(get) ;
// response 实体
HttpEntity entity = httpResponse.getEntity() ;
if ( null != entity) {
String response = EntityUtils. toString(entity) ;
int statusCode = httpResponse.getStatusLine().getStatusCode() ;
LOGGER.info( " 响应状态码 :" + statusCode) ;
LOGGER.info( " 响应内容 :" + response) ;
if (statusCode == HttpStatus. SC_OK) {
// 成功
return response ;
} else {
return null;
}
}
return null;
} catch (IOException e) {
LOGGER.error( "httpclient 请求失败 " , e) ;
return null;
} finally {
if (httpResponse != null) {
try {
EntityUtils. consume(httpResponse.getEntity()) ;
httpResponse.close() ;
} catch (IOException e) {
LOGGER.error( " 关闭 response 失败 " , e) ;
}
}
}
}
}
private static Logger LOGGER = LoggerFactory. getLogger(HttpRequest. class) ;
private static PoolingHttpClientConnectionManager cm = null;
static {
LayeredConnectionSocketFactory sslsf = null;
try {
sslsf = new SSLConnectionSocketFactory(SSLContext. getDefault()) ;
} catch (NoSuchAlgorithmException e) {
LOGGER.error( " 创建 SSL 连接失败 ") ;
}
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create()
.register( "https" , sslsf)
.register( "http" , new PlainConnectionSocketFactory())
.build() ;
cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry) ;
cm.setMaxTotal( 200) ;
cm.setDefaultMaxPerRoute( 20) ;
}
private static CloseableHttpClient getHttpClient() {
CloseableHttpClient httpClient = HttpClients. custom()
.setConnectionManager( cm)
.build() ;
return httpClient ;
}
public static String get(String url , String param) {
// 创建默认的 httpClient 实例
CloseableHttpClient httpClient = HttpRequest. getHttpClient() ;
CloseableHttpResponse httpResponse = null;
// 发送 get 请求
try {
// 用 get 方法发送 http 请求
HttpGet get = new HttpGet(url + URLEncoder. encode(param , "UTF-8")) ;
LOGGER.info( " 执行 get 请求 , uri: " + get.getURI()) ;
httpResponse = httpClient.execute(get) ;
// response 实体
HttpEntity entity = httpResponse.getEntity() ;
if ( null != entity) {
String response = EntityUtils. toString(entity) ;
int statusCode = httpResponse.getStatusLine().getStatusCode() ;
LOGGER.info( " 响应状态码 :" + statusCode) ;
LOGGER.info( " 响应内容 :" + response) ;
if (statusCode == HttpStatus. SC_OK) {
// 成功
return response ;
} else {
return null;
}
}
return null;
} catch (IOException e) {
LOGGER.error( "httpclient 请求失败 " , e) ;
return null;
} finally {
if (httpResponse != null) {
try {
EntityUtils. consume(httpResponse.getEntity()) ;
httpResponse.close() ;
} catch (IOException e) {
LOGGER.error( " 关闭 response 失败 " , e) ;
}
}
}
}
}