Пул соединений HTTP с использованием HttpClient

  • Как создать пул соединений с помощью HttpClient?
  • Я должен часто подключаться к одному и тому же серверу. Стоит ли создавать такой пул?
  • можно ли сохранить живые соединения и использовать его для различных запросов, и если да, то как я могу это сделать?

Я разрабатываю на Java, используя Apache HTTP Client.

7 ответов


[предполагая Java и HttpClient Apache]

использовать ThreadSafeClientConnManager. Передайте один глобальный экземпляр конструктору каждого экземпляра HttpClient. Я не думаю, что есть какой-то смысл в объединении самих HttpClients.


PoolingClientConnectionManager теперь устарел . из (4.3 версии) использовать PoolingHttpClientConnectionManager.


ThreadSafeClientConnManager устарел, используйте PoolingClientConnectionManager вместо.


Я провел последние дни, работая над этим, поэтому просто хочу поделиться некоторыми" всеми известными " знаниями с вами.

во-первых, поскольку вы имеете дело с одним и тем же сервером, рекомендуется использовать один HTTP-клиент для выполнения ваших запросов. С помощью PoolingHttpClientConnectionManager ваш клиент может быть использован для выполнения нескольких запросов одновременно. Официальный пример многопоточного выполнения запроса можно найти здесь.

во-вторых, HTTP / 1.1 (и расширенные версии HTTP / 1.0) позволяет HTTP-клиентам сохранять соединения открытыми после завершения транзакций, чтобы их можно было повторно использовать для будущих запросов. Это часто упоминается как Постоянное Соединение.

также с целью повторного использования клиента для нескольких запросов заголовок ответа с сервера часто включает вызов атрибута Keep-Alive которые содержат время текущее соединение будет сохранено в живых. Кроме того, Apache Http Client также предоставляет вам интерфейс ConnectionKeepAliveStrategyв настройте собственную политику повторного использования соединения.


для HttpClient 4x:

ThreadSafeClientConnManager ... управляет пул клиентов соединения и может обслуживать запросы на подключение из нескольких потоков выполнения.

соединения объединяются в пул на основе маршруту. Запрос на маршрут, для которого менеджер уже имеет постоянное соединение, доступное в бассейне, будет обслуживаться лизингом подключение бассейн а не создание нового соединения.

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


Это пример пула соединений 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 уже имеет пул соединений.Поэтому вам не нужно его создавать. Просто использовать его.