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);
        }
    }
}