简体   繁体   English

使用 HttpClient 的 HTTP 连接池

[英]HTTP connection pooling using HttpClient

  • How can I create a pool of connections using HttpClient?如何使用 HttpClient 创建连接池?
  • I have to make frequent connections to the same server.我必须经常连接到同一台服务器。 Is it worth creating such a pool?是否值得创建这样的池?
  • Is it possible to keep live connections and use it for various requests, and if yes how can I do so?是否可以保持实时连接并将其用于各种请求,如果是,我该怎么做?

I am developing in Java, using Apache HTTP Client .我正在 Java 中开发,使用Apache HTTP Client

I have spent recent days working on this so just want to share some "everyone-known" knowledges with you.我最近几天都在研究这个,所以只想与您分享一些“人人皆知”的知识。

First, as you are dealing with the same server, it is recommended to use a single HTTP client to execute your requests.首先,当您处理同一台服务器时,建议使用单个 HTTP 客户端来执行您的请求。 With the help of PoolingHttpClientConnectionManager , your client can be used to execute multiple requests concurrently.PoolingHttpClientConnectionManager的帮助下,您的客户端可用于同时执行多个请求。 The official example of multithreaded request execution can be found here .多线程请求执行的官方示例可以在这里找到。

Secondly, HTTP/1.1 (and enhanced versions of HTTP/1.0) allows HTTP clients to keep the connections open after transactions complete so that it can be reused for future requests.其次,HTTP/1.1(和 HTTP/1.0 的增强版本)允许 HTTP 客户端在事务完成后保持连接打开,以便它可以被重用于未来的请求。 This is often refered as Persistent Connection .这通常被称为持久连接

Also for the purpose of reusing client for multiple requests, the response header from a server often include an attribute call Keep-Alive that contain the time current connection will be kept alive.同样为了对多个请求重用客户端,来自服务器的响应头通常包含一个属性调用Keep-Alive ,其中包含当前连接将保持活动的时间。 Besides that, Apache Http Client also provides you an interface ConnectionKeepAliveStrategy to customize your own policy for reusing connection.除此之外,Apache Http Client 还为您提供了一个接口ConnectionKeepAliveStrategy来自定义您自己的重用连接策略。

PoolingClientConnectionManager is Deprecated now . PoolingClientConnectionManager现在已弃用。 from (4.3 version) use PoolingHttpClientConnectionManager .从(4.3 版)使用PoolingHttpClientConnectionManager

[assuming Java, and Apache's HttpClient] [假设 Java 和 Apache 的 HttpClient]

Use a ThreadSafeClientConnManager .使用ThreadSafeClientConnManager Pass a single global instance to the constructor of every HttpClient instance.将单个全局实例传递给每个 HttpClient 实例的构造函数。 I don't think there's any point in pooling the HttpClients themselves.我认为将 HttpClient 本身集中起来没有任何意义。

ThreadSafeClientConnManager 现在已弃用,请改用PoolingClientConnectionManager

For HttpClient 4x:对于 HttpClient 4x:

ThreadSafeClientConnManager ... manages a pool of client connections and is able to service connection requests from multiple execution threads. ThreadSafeClientConnManager ... 管理客户端连接池,并能够为来自多个执行线程的连接请求提供服务。

Connections are pooled on a per route basis .连接在每个路由的基础上汇集 A request for a route for which the manager already has a persistent connection available in the pool will be serviced by leasing a connection from the pool rather than creating a brand new connection.对于管理器已经在池中具有可用持久连接的路由的请求,将通过从池中租用连接而不是创建全新的连接来提供服务。

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

This is an example of an Apache HttpClient 4.3 pool of connections which do not require authentication:这是不需要身份验证的 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

HttpClient has already have a connection pool.So you do not need to create it. HttpClient 已经有一个连接池,所以你不需要创建它。 Just use it.就用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM