HTTPClient 连接池

桃扇骨 2021-11-29 19:34 469阅读 0赞

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

maven依赖

  1. <dependency>
  2. <groupId>org.apache.httpcomponents</groupId>
  3. <artifactId>httpclient</artifactId>
  4. </dependency>

连接管理器参数设置

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

HTTPClient 连接管理器

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

  1. @Bean
  2. public PoolingHttpClientConnectionManager poolingConnectionManager() {
  3. // 创建服务连接对象
  4. SSLContextBuilder builder = new SSLContextBuilder();
  5. // 连接池管理器初始化
  6. try {
  7. builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
  8. } catch (NoSuchAlgorithmException | KeyStoreException e) {
  9. logger.error("Pooling Connection Manager Initialisation failure because of " + e.getMessage(), e);
  10. }
  11. // 客户端验证服务器身份的策略
  12. SSLConnectionSocketFactory sslsf = null;
  13. try {
  14. sslsf = new SSLConnectionSocketFactory(builder.build());
  15. } catch (KeyManagementException | NoSuchAlgorithmException e) {
  16. logger.error("Pooling Connection Manager Initialisation failure because of " + e.getMessage(), e);
  17. }
  18. assert sslsf != null : "SSLConnectionSocketFactory must not = null!";
  19. // 设置协议http和https对应的处理socket链接工厂的对象
  20. // 协议方案
  21. Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
  22. .<ConnectionSocketFactory>create()
  23. .register("https", sslsf)
  24. .register("http", new PlainConnectionSocketFactory())
  25. .build();
  26. // 创建已经注册的连接管理器
  27. PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
  28. // 配置持久连接的最大限制,保持在连接池或由连接管理器租用
  29. poolingConnectionManager.setMaxTotal(MAX_TOTAL_CONNECTIONS);
  30. return poolingConnectionManager;
  31. }

HTTPClient 复用持久性连接

  • 当有连接第一次使用的时候建立连接
  • 结束时对应连接不关闭,归还到池中
  • 下次同个目的的连接可从池中获取一个可用连接
  • 定期清理过期连接

    @Bean

    1. public ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
    2. // 根据重用策略判断当前连接是否要复用
    3. return (response, context) -> {
    4. HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
    5. while (it.hasNext()) {
    6. HeaderElement he = it.nextElement();
    7. String param = he.getName();
    8. String value = he.getValue();
    9. if (value != null && "timeout".equalsIgnoreCase(param)) {
    10. return Long.parseLong(value) * 1000;
    11. }
    12. }
    13. return DEFAULT_KEEP_ALIVE_TIME_MILLIS; // 保持连接
    14. };
    15. }

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

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

  1. @Bean
  2. public CloseableHttpClient httpClient() {
  3. // 设置请求的配置
  4. RequestConfig requestConfig = RequestConfig.custom()
  5. .setConnectionRequestTimeout(REQUEST_TIMEOUT)
  6. .setConnectTimeout(CONNECT_TIMEOUT)
  7. .setSocketTimeout(SOCKET_TIMEOUT).build();
  8. return HttpClients.custom()
  9. .setDefaultRequestConfig(requestConfig) // 请求的配置
  10. .setConnectionManager(poolingConnectionManager()) // 连接池管理器
  11. .setKeepAliveStrategy(connectionKeepAliveStrategy()) // 连接是否复用
  12. .build();
  13. }

发表评论

表情:
评论列表 (有 0 条评论,469人围观)

还没有评论,来说两句吧...

相关阅读

    相关 HTTPClient 连接

      向Dirud集群写入数据时,采用HTTPClient向集群提交数据,由于数据量大,需要以多线程方式开启多个线程,单个的HTTPClient会出现连接超时,效率低的情况。高