您的位置:首页 > 理论基础 > 计算机网络

HttpClient工具正确使用方式

2016-07-25 17:55 489 查看
虽然现在基于netty和thift的微服务非常的流行,但是公司内部的蛮多系统仍然对外提供http接口。在调用http接口工具类中,apache httpclient工具用的比较多。下面列举一些正确使用httpclient的一些要点。


设置socketTimeout

可以在
RequestConfig
 中设置socketTimeout,表示数据传输处理时间,如下:
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(4000).build()
1


设置connectionRequestTimeout

可以在
RequestConfig
 中设置socketTimeout,表示从连接池中后去连接的timeout时间,如下:
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(1000)
1


设置connectTimeout

可以在
RequestConfig
 中设置connectTimeout,表示建立连接的timeout时间,如下:
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(3000).build();
1


设置MaxTotal

MaxTotal表示连接池最大并发连接数,代码如下:
PoolingHttpClientConnectionManager pccm = new PoolingHttpClientConnectionManager();
pccm.setMaxTotal(300);
1
2


设置DefaultMaxPerRout

DefaultMaxPerRout表示单路由的最大并发连接数,假设你的业务系统需要调用A和B这两个外部系统的http接口,那么如果DefaultMaxPerRout=100,那么调用A系统的http接口时,最大并发数就是100。代码如下:
PoolingHttpClientConnectionManager pccm = new PoolingHttpClientConnectionManager();
pccm.setDefaultMaxPerRoute(100); // 单路由最大并发数
1
2


尽量不要设置超时重试次数

如果要设置的话,可以如下设置:
// 设置默认时间
RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(1000).setSocketTimeout(4000)
.setExpectContinueEnabled(true).build();

PoolingHttpClientConnectionManager pccm = new PoolingHttpClientConnectionManager(); pccm.setMaxTotal(300);// 连接池最大并发连接数
pccm.setDefaultMaxPerRoute(50); // 单路由最大并发数
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(IOException exception , int executionCount , HttpContext context) {
if (executionCount > 3) {
return false;
}
if (exception instanceof NoHttpResponseException) {
LOGGER.info(
"[NoHttpResponseException has retry request:" + context.toString() + "][executionCount:" + executionCount + "]");
return true;
}
else if (exception instanceof SocketException) {
LOGGER.info("[SocketException has retry request:" + context.toString() + "][executionCount:" + executionCount + "]");
return true;
}
return false;
}
};
httpclient = HttpClients.custom().setConnectionManager(pccm).setDefaultRequestConfig(params).setRetryHandler(retryHandler)
.build();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26


完整代码

package test;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;

public class HttpClientUtils {
private final static Logger LOGGER = LoggerFactory.getLogger(HttpClientUtils.class);

private final static String UTF8 = "UTF-8";

public static CloseableHttpClient httpclient = null;

static {
// 初始化线程池
RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(1000).setSocketTimeout(4000)
.setExpectContinueEnabled(true).build();

PoolingHttpClientConnectionManager pccm = new PoolingHttpClientConnectionManager(); pccm.setMaxTotal(300);// 连接池最大并发连接数
pccm.setDefaultMaxPerRoute(50); // 单路由最大并发数

HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(IOException exception , int executionCount , HttpContext context) {
// 重试1次,从1开始
if (executionCount > 1) {
return false;
}
if (exception instanceof NoHttpResponseException) {
LOGGER.info(
"[NoHttpResponseException has retry request:" + context.toString() + "][executionCount:" + executionCount + "]");
return true;
}
else if (exception instanceof SocketException) {
LOGGER.info("[SocketException has retry request:" + context.toString() + "][executionCount:" + executionCount + "]");
return true;
}
return false;
}
};
httpclient = HttpClients.custom().setConnectionManager(pccm).setDefaultRequestConfig(params).setRetryHandler(retryHandler)
.build();
}

public static String post(String urlToRequest , Map<String, Object> parameters , Integer connectionRequestTimeout ,
Integer connectTimeout , Integer socketTimeout) {

Long startTs = System.currentTimeMillis();
List<NameValuePair> nvps = new ArrayList<NameValuePair>();

if (parameters != null && !parameters.isEmpty()) {
for (Entry<String, Object> entry : parameters.entrySet()) {
nvps.add(new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())));
}
}

try {
LOGGER.info("post-req:url:{},param:{}", urlToRequest, JSON.toJSONString(parameters));
HttpPost post = new HttpPost(urlToRequest);

if (connectionRequestTimeout != null && connectTimeout != null && socketTimeout != null) {
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout).setSocketTimeout(socketTimeout).build();
post.setConfig(requestConfig);
}
post.setEntity(new UrlEncodedFormEntity(nvps, UTF8));

String result = invoke(post);
Long endTs = System.currentTimeMillis();
Long currentMethodCallTime = endTs - startTs;
if (currentMethodCallTime > 5000) {
LOGGER.warn("url:{},call time {} ms", urlToRequest, currentMethodCallTime);
LOGGER.info("所有存活线程="+Thread.getAllStackTraces().size());
}
LOGGER.info("post-rps:{}", result);
return result;
}
catch (UnsupportedEncodingException e) {
LOGGER.error("[HttpClientUtils][post][Unsupported Encoding Exception]", e);
}
return null;
}

private static String invoke(HttpUriRequest request) {
CloseableHttpResponse response = null;
try {
response = httpclient.execute(request);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
return EntityUtils.toString(entity, UTF8);
}
}
catch (IOException e) {
LOGGER.error(
"[HttpClientUtils][invoke][method:" + request.getMethod() + " URI:" + request.getURI() + "] is request exception", e);
}
finally {
if (response != null) {
try {
response.close();
}
catch (IOException e) {
LOGGER.error(
"[HttpClientUtils][invoke][method:" + request.getMethod() + " URI:" + request.getURI() + "] is closed exception",
e);
}
}
}
return null;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: