2015-01-10 1 views
0

Я использую много http-соединения с Apache HttpClient (org.apache.httpcomponents 4.3.6) для проверки серверов, и я не могу заставить соединения закрываться, даже когда я планирую HttpConnectionManager до httpClient.getConnectionManager().shutdown(); через 10 секунд в другом потоке.Как заставить Apache HttpClient/HttpConnection полностью закрыть соединение tcp?

httpClient.close() тоже не поможет.

Соединения могут длиться минут или даже часов.

Я попытался пользовательские SocketConfig и это тоже не помогает:

SocketConfig socketConfig = SocketConfig.custom() 
       .setSoKeepAlive(false) 
       .setSoLinger(5) 
       .setSoReuseAddress(true) 
       .setSoTimeout(5000) 
       .setTcpNoDelay(true).build(); 

Путь, я извлечение содержимого:

HttpUriRequest request = new HttpGet(url); 
    HttpResponse response = httpClient.execute(request); 

    try (InputStream in = response.getEntity().getContent()) { 
     String result = IOUtils.toString(in, StandardCharsets.UTF_8); 
     httpClient.close(); 
     return result; 
    } 

Как я строю HTTP Client:

SocketConfig socketConfig = SocketConfig.custom() 
      .setSoKeepAlive(false) 
      .setSoLinger(configuration.getInt("proxy.list.socket.so.linger")) 
      .setSoReuseAddress(true) 
      .setSoTimeout(configuration.getInt("proxy.list.socket.so.timeout")) 
      .setTcpNoDelay(true).build(); 

    HttpClientBuilder builder = HttpClientBuilder.create(); 
    builder.disableAutomaticRetries(); 
    builder.disableContentCompression(); 
    builder.disableCookieManagement(); 
    builder.disableRedirectHandling(); 
    builder.setConnectionReuseStrategy(new NoConnectionReuseStrategy()); 
    builder.setDefaultSocketConfig(socketConfig); 

Один из моих прототипов закрытия:

 shutdownExecutor.schedule(() -> { 
      httpClient.getConnectionManager().closeExpiredConnections(); 
      httpClient.getConnectionManager().closeIdleConnections(1, TimeUnit.SECONDS); 
      httpClient.getConnectionManager().shutdown(); 

      httpClient.notifyAll(); 
      try { 
       httpClient.close(); 
      } catch (IOException ex) { 

      } 

     }, configuration.getInt("proxy.test.forced.timeout.seconds"), TimeUnit.SECONDS); 

     String content = HttpContentFetcher.getAndCloseClient(url, httpClient); 
+0

Можете ли вы разместить минимальный образец? Как вы пытаетесь закрыть соединение и почему вы заявляете, что это не влияет? – Raffaele

+0

@ Raffaele Это потрясающий ответ на чтение. Вложенные детали. На самом деле я уверен, что я достиг тайм-аута, но длиной около 300 секунд, а не 10 секунд, как я хочу. –

+0

Это странно, что вы используете сокет в своем коде и ожидаете, что сокет будет закрыт сразу же в одно и то же время. – oleg

ответ

0

RequestConfig помог. Теперь похоже, что все соединения отбрасываются в определенных пределах.

 RequestConfig config= RequestConfig.custom() 
       .setCircularRedirectsAllowed(false) 
       .setConnectionRequestTimeout(4000) 
       .setConnectTimeout(4000) 
       .setMaxRedirects(0) 
       .setRedirectsEnabled(false) 
       .setSocketTimeout(4000) 
       .setStaleConnectionCheckEnabled(true).build(); 
     request.setConfig(config); 
Смежные вопросы