HttpClient工具正确使用方式
2016-07-25 17:55
489 查看
虽然现在基于netty和thift的微服务非常的流行,但是公司内部的蛮多系统仍然对外提供http接口。在调用http接口工具类中,apache httpclient工具用的比较多。下面列举一些正确使用httpclient的一些要点。
可以在
可以在
可以在
MaxTotal表示连接池最大并发连接数,代码如下:
2
DefaultMaxPerRout表示单路由的最大并发连接数,假设你的业务系统需要调用A和B这两个外部系统的http接口,那么如果DefaultMaxPerRout=100,那么调用A系统的http接口时,最大并发数就是100。代码如下:
2
如果要设置的话,可以如下设置:
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
设置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
尽量不要设置超时重试次数
如果要设置的话,可以如下设置:// 设置默认时间1
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();
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;
}
}
相关文章推荐
- Python3网络爬虫(四): 登录
- MPTCP - Linux Kernel MultiPath TCP project
- Java网络编程
- TCP/IP的Socket编程
- Android学习笔记036之网络数据解析
- tcpreplay工具使用
- [C#]Ajax XMLHttp 对象的获取方法
- 小白学Tensorflow之简单神经网络
- 利用Openfiler配置基于文件系统的网络存储
- linux网络虚拟化
- HBuilder网络联网提示
- java学习之Tcp网络程序
- 浅谈httpd的了解
- 网络编程的一些错误总结
- POJ 1459最大流模板
- 【TCP/IP】检验和算法
- 关于Android使用HttpURLConnection传输含有中文JSON数据的报错、乱码问题
- 基于TCP的socket编程
- 简述TCP和UDP协议并举例说明它们的区别
- Ubuntu 配置 Nginx http2.0 支持 (二) 编译&配置Nginx 与 pagespeed