Pool de conexões HTTP usando o HttpClient

  • Como posso criar um pool de conexões usando o HttpClient?
  • Eu tenho que fazer conexões freqüentes para o mesmo servidor. Vale a pena criar essa piscina?
  • É possível manter conexões ao vivo e usá-lo para várias solicitações e, se sim, como posso fazer isso?

Estou desenvolvendo em Java, usando o Apache HTTP Client .

[assumindo o Java e o HttpClient do Apache]

Use um ThreadSafeClientConnManager . Passar uma única instância global para o construtor de cada instância HttpClient. Eu não acho que haja algum ponto em agrupar os HttpClients.

PoolingClientConnectionManager está obsoleto agora. de (versão 4.3) use PoolingHttpClientConnectionManager .

ThreadSafeClientConnManager está obsoleto agora, use PoolingClientConnectionManager .

Eu passei os últimos dias trabalhando nisso, então apenas quero compartilhar alguns conhecimentos “conhecidos por todos” com você.

Primeiro, como você está lidando com o mesmo servidor, é recomendável usar um único cliente HTTP para executar suas solicitações. Com a ajuda do PoolingHttpClientConnectionManager , seu cliente pode ser usado para executar várias solicitações ao mesmo tempo. O exemplo oficial de execução de solicitação multithread pode ser encontrado aqui .

Em segundo lugar, o HTTP / 1.1 (e versões aprimoradas do HTTP / 1.0) permite que os clientes HTTP mantenham as conexões abertas após as transactions serem concluídas, para que possam ser reutilizadas para futuras solicitações. Isso geralmente é referido como Conexão Persistente .

Também com o objective de reutilizar o cliente para várias solicitações, o header de resposta de um servidor geralmente inclui uma chamada de atributo Keep-Alive que contém a hora em que a conexão atual será mantida ativa. Além disso, o Apache Http Client também fornece uma interface ConnectionKeepAliveStrategy para personalizar sua própria política de reutilização de conexão.

Para o HttpClient 4x:

ThreadSafeClientConnManager … gerencia um pool de conexões de clientes e é capaz de atender solicitações de conexão de vários threads de execução.

As conexões são agrupadas por rota . Uma solicitação para uma rota para a qual o gerente já tem uma conexão persistente disponível no pool será atendida pelo leasing de uma conexão do pool, em vez de criar uma nova conexão.

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

Este é um exemplo de um conjunto de conexões Apache HttpClient 4.3 que não requerem autenticação:

 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 já tem um pool de conexão. Então você não precisa criá-lo. Apenas use isso.