HttpClient 参数介绍 含工具类,可直接copy使用
timeToLive : 连接存活时间,默认永不过期,建议使用默认值即可不需要配置,这样会使用服务器返回的keepalive,只要在keepalive时间范围内,连接就不会关闭。
setValidateAfterInactivity :连接校验时间,默认2000ms,超过当前设置时间每次从连接池获取的连接,都会进行 socket 连接校验,看连接是否有效,时间越短越不容易拿到无效的连接,建议使用默认值即可不需要配置
defaultMaxPerRoute :每个服务器最大连接数,默认是2,这个配置就要看具体的调用的域名的数量,比如最大连接数50,调用了10个域名,那么这个defaultMaxPerRoute设置为5即可
调用服务器个数
defaultMaxPerRoute= maxTotal/ 调用服务器个数maxTotal: 整个连接池的最大连接数。包括所有路由的连接。当连接池中的当前连接数达到maxTotal时,将不再允许创建新的连接,直到现有连接被释放或超时,这个就要根据自身具体的业务,包括服务器的负载,通过连接池的监控调整对应的大小,建议不要设置过大。
evictExpiredConnections: 清除过期时间的连接,后台启动定时任务,关闭过期的连接,需要与 timeToLive 配合使用
evictIdleConnections : 清除空闲的连接,与上面配置一样后台启动定时任务,关闭空闲连接,推荐配置,在没有请求的时候,节约服务器的资源
HttpUtil代码
最后HttpUtil完整代码案例,大家可用copy直接使用,具体的配置大家还是要根据自身的业务场景不同去设置
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.pool.PoolStats;
import org.apache.http.util.EntityUtils;
import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class HttpUtil {
/**
* 从连接管理器请求连接时使用的超时时间(单位/毫秒)
* 默认值: -1,为无限超时。
*/
private final static int connectionRequestTimeout = 5000;
/**
* 确定建立连接之前的超时时间(单位/毫秒)
* 默认值: -1,为无限超时。
*/
private final static int connectTimeout = 5000;
/**
* 待数据的超时(单位/毫秒)
* 默认值: -1,为无限超时。
*/
private final static int socketTimeout = 5000;
/**
* 连接池最大连接数
* 默认值:20
*/
private final static int maxTotal = 50;
/**
* 每个路由最大连接数
* 默认值:2
*/
private final static int maxPreRoute = 4;
/**
* 连接存活时长:秒
*/
private final static long connectionTimeToLive = 60;
/**
* 重试尝试最大次数
* 默认为3
*/
private final static int retryCount = 3;
/**
* 非幂等请求是否可以重试
* 默认不开启
*/
private final static boolean requestSentRetryEnabled = false;
/**
* Http客户端
*/
public static final CloseableHttpClient httpClient;
public static final PoolingHttpClientConnectionManager connectionManager;
static {
// 配置请求参数
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setConnectionRequestTimeout(connectionRequestTimeout)
.setSocketTimeout(socketTimeout)
.build();
connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(maxTotal);
connectionManager.setDefaultMaxPerRoute(maxPreRoute);
// 初始化客户端
httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(requestConfig)
// 重试机制
.setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, requestSentRetryEnabled))
// 开启后台线程清除闲置的连接
.evictIdleConnections(connectionTimeToLive, TimeUnit.SECONDS)
.build();
// 添加监控线程,创建一个定时线程池
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
// 每隔1s打印连接池信息
executor.scheduleAtFixedRate(HttpUtil::httpPoolStats, 0, 1, TimeUnit.SECONDS);
}
public static void httpPoolStats() {
// 获取所有路由的连接池状态
PoolStats totalStats = connectionManager.getTotalStats();
System.out.println("time " + new Date() + " Total status:" + totalStats.toString());
}
public static void main(String[] args) {
//使用方法
HttpGet get = new HttpGet("https://www.baidu.com/");
CloseableHttpResponse response = null;
try {
response = HttpUtil.httpClient.exec`ute(get);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity resEntity = response.getEntity();
String message = null;
message = EntityUtils.toString(resEntity, "UTF-8");
System.out.println(message);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}