HTTPClient 连接池

 

向Dirud集群写入数据时,采用HTTPClient向集群提交数据,由于数据量大,需要以多线程方式开启多个线程,单个的HTTPClient会出现连接超时,效率低的情况。高并发的情况下,提高HTTP的请求效率,可以使用HTTPClient连接池的方式,减少3次握手的次数。

maven依赖

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

连接管理器参数设置

private static final int CONNECT_TIMEOUT = 5000; // 建立连接的超时连接
private static final int REQUEST_TIMEOUT = 5000; // 等待连接池返回可用连接的超时时间
private static final int SOCKET_TIMEOUT = 5000; // 服务器读超时时间
private static final int MAX_TOTAL_CONNECTIONS = 8000; // 总超时
private static final int DEFAULT_KEEP_ALIVE_TIME_MILLIS = 20 * 1000; // keep-alive
private static final int CLOSE_IDLE_CONNECTION_WAIT_TIME_SECS = 30; // 空闲连接释放时间(秒)

HTTPClient 连接管理器

PoolingHttpClientConnectionManagerd 是 HttpClient 默认的连接管理器,对连接进行池化管理。从原来的org.apache.http.conn.ssl 包挪到了org.apache.http.ssl 包,基本用法不变。

    @Bean
    public PoolingHttpClientConnectionManager poolingConnectionManager() {
        // 创建服务连接对象
        SSLContextBuilder builder = new SSLContextBuilder();
        // 连接池管理器初始化
        try {
            builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
        } catch (NoSuchAlgorithmException | KeyStoreException e) {
            logger.error("Pooling Connection Manager Initialisation failure because of " + e.getMessage(), e);
        }
        // 客户端验证服务器身份的策略
        SSLConnectionSocketFactory sslsf = null;
        try {
            sslsf = new SSLConnectionSocketFactory(builder.build());
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            logger.error("Pooling Connection Manager Initialisation failure because of " + e.getMessage(), e);
        }
        assert sslsf != null : "SSLConnectionSocketFactory must not = null!";
        // 设置协议http和https对应的处理socket链接工厂的对象
        // 协议方案
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
                .<ConnectionSocketFactory>create()
                .register("https", sslsf)
                .register("http", new PlainConnectionSocketFactory())
                .build();
        // 创建已经注册的连接管理器
        PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
        // 配置持久连接的最大限制,保持在连接池或由连接管理器租用
        poolingConnectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
        return poolingConnectionManager;
    }

HTTPClient 复用持久性连接

  • 当有连接第一次使用的时候建立连接
  • 结束时对应连接不关闭,归还到池中
  • 下次同个目的的连接可从池中获取一个可用连接
  • 定期清理过期连接
    @Bean
    public ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
        // 根据重用策略判断当前连接是否要复用
        return (response, context) -> {
            HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
            while (it.hasNext()) {
                HeaderElement he = it.nextElement();
                String param = he.getName();
                String value = he.getValue();
                if (value != null && "timeout".equalsIgnoreCase(param)) {
                    return Long.parseLong(value) * 1000;
                }
            }
            return DEFAULT_KEEP_ALIVE_TIME_MILLIS; // 保持连接
        };
    }

创建HttpClient对象,给httpclient设置连接管理器

一般通过CloseableHttpClient httpClient = HttpClients.custom().build();获取到一个httpClient。HttpClients.custom().build()方法中构造把处理链构造起来。

    @Bean
    public CloseableHttpClient httpClient() {
        // 设置请求的配置
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(REQUEST_TIMEOUT)
                .setConnectTimeout(CONNECT_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT).build();
        return HttpClients.custom()
                .setDefaultRequestConfig(requestConfig) // 请求的配置
                .setConnectionManager(poolingConnectionManager()) // 连接池管理器
                .setKeepAliveStrategy(connectionKeepAliveStrategy()) // 连接是否复用
                .build();
    }

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值