【问题标题】:Connection pooling in java using HttpClient [closed]使用 HttpClient 的 HTTP 连接池
【发布时间】:2011-06-18 14:27:16
【问题描述】:
  • 如何使用 HttpClient 创建连接池?
  • 我必须频繁连接到同一台服务器。是否值得创建这样一个池?
  • 是否可以保持实时连接并将其用于各种请求,如果可以,我该怎么做?

我正在使用 Java 进行开发,使用 Apache HTTP Client

【问题讨论】:

标签: java httpclient httpconnection pooling


【解决方案1】:

[假设 Java 和 Apache 的 HttpClient]

使用ThreadSafeClientConnManager。将单个全局实例传递给每个 HttpClient 实例的构造函数。我认为汇集 HttpClients 本身没有任何意义。

【讨论】:

  • 后来换成了org.apache.http.impl.conn.PoolingHttpClientConnectionManager
  • 所有方法和构造函数在 ThreadSafeClientConnManager 的文档中都被标记为 deprecated
【解决方案2】:

对于 HttpClient 4x:

ThreadSafeClientConnManager ...管理一个客户端池 连接,并且能够为来自多个执行线程的连接请求提供服务。

连接按路由合并。对经理已经为之的路线的请求 在池中有一个可用的持久连接将通过租用 连接来提供服务 池,而不是创建一个全新的连接。

http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html

【讨论】:

    【解决方案3】:

    ThreadSafeClientConnManager 现已弃用,请改用PoolingClientConnectionManager

    【讨论】:

    【解决方案4】:

    PoolingClientConnectionManager 现已弃用。从(4.3版本)使用PoolingHttpClientConnectionManager

    【讨论】:

    【解决方案5】:

    这是一个不需要身份验证的 Apache HttpClient 4.3 连接池示例:

    public class PoolOfHttpConnections{
       static String[] urisToGet = {"http://www.site1.com", "http://www.site2.com"};
    
        public static void main(String[] args) throws Exception {
               CloseableHttpClient httpclient = HttpClients.createDefault();
               // create a thread for each link
               GetThread[] threads = new GetThread[urisToGet.length];
               for (int i = 0; i < threads.length; i++) {
                   HttpGet httpget = new HttpGet(urisToGet[i]);
                   threads[i] = new GetThread(httpClient, httpget);
               }
    
               // start the threads
               for (int j = 0; j < threads.length; j++) {
                   threads[j].start();
               }
               // join the threads
               for (int j = 0; j < threads.length; j++) {
                   threads[j].join();
               }
        } //end main
    
        private static class GetThread extends Thread {
    
                private final CloseableHttpClient httpClient;
                private final HttpContext context;
                private final HttpGet httpget;
    
                public GetThread(CloseableHttpClient httpClient, HttpGet httpget) {
                       this.httpClient = httpClient;
                       this.context = HttpClientContext.create();
                       this.httpget = httpget;
                }
    
                @Override
                public void run() {
                       try {
                           CloseableHttpResponse response = httpClient.execute(httpget, context);
                           try {
                               HttpEntity entity = response.getEntity();
                               System.out.println("----------------------------------------");
                               Date date = new Date();
                               System.out.println("Beginning*******************");
                               System.out.println(date.toString());
                               System.out.println("There are "+urisToGet.length+" threads running in parallel!");
                               System.out.println(response.getStatusLine());
                               if (entity != null) {
                                  System.out.println("Response content length: " + entity.getContentLength());
                               }
                               System.out.println(EntityUtils.toString(entity));
                               EntityUtils.consume(entity);
                           } finally {
                             response.close();
                             System.out.println("End*******************");
                           }
                       } catch (ClientProtocolException ex) {
                              // Handle protocol errors
                       } catch (IOException ex) {
                              // Handle I/O errors
                       }
                }
        } /*end private class*/  }//end public class PoolOfHttpConnections
    

    【讨论】:

      【解决方案6】:

      HttpClient 已经有一个连接池,所以你不需要创建它。随便用吧。

      【讨论】:

      • 这绝对是错误的。 Httpclient默认没有连接池
      【解决方案7】:

      我最近几天都在研究这个,所以只想和你分享一些“众所周知”的知识。

      首先,由于您处理的是同一台服务器,因此建议使用单个 HTTP 客户端来执行您的请求。在PoolingHttpClientConnectionManager 的帮助下,您的客户端可用于同时执行多个请求。多线程请求执行的官方示例可见here

      其次,HTTP/1.1(和 HTTP/1.0 的增强版本)允许 HTTP 客户端在事务完成后保持连接打开,以便可以将其重用于未来的请求。这通常称为持久连接

      同样为了对多个请求重用客户端,来自服务器的响应头通常包含一个属性调用Keep-Alive,其中包含当前连接保持活动的时间。除此之外,Apache Http Client 还为您提供了一个接口ConnectionKeepAliveStrategy来自定义您自己的重用连接策略。

      【讨论】:

      • 只是想知道,什么时候可以在ConnectionConfig 中为4.x 之前的每个HttpClient 设置连接超时和套接字超时,现在它们在PoolingHttpClientConnectionManager 中不存在。现在,如何设置超时?还有,在哪里设置http.conn-manager.timeout 是在获得连接之前等待的时间?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多