【问题标题】:How to force Apache HttpClient / HttpConnection to absolutely close tcp connection?如何强制 Apache HttpClient / HttpConnection 绝对关闭 tcp 连接?
【发布时间】:2015-01-10 15:57:08
【问题描述】:

我使用 Apache HttpClient (org.apache.httpcomponents 4.3.6) 的大量 http 连接来测试服务器,我无法强制关闭连接,即使我在另一个线程中安排 HttpConnectionManagerhttpClient.getConnectionManager().shutdown(); 10 秒后.

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 客户端的方式:

    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);

【问题讨论】:

  • 你能发布一个最小的样本吗?你如何尝试关闭连接,为什么你说它没有效果?
  • @Raffaele 它停留在阅读响应上。粘贴细节。实际上我很确定我已经实现了超时,但长度约为 300 秒,而不是我想要的 10 秒。
  • 在代码中使用 socket linger 并期望套接字同时立即关闭,这有点奇怪。
  • @oleg 你能提供一些细节吗?我不知道因此参数的确切含义,但我只是希望它具有 KNOWN 值,以确保它不是 0=无限制。
  • SO_LINGER 参数(包括零延迟)及其与 TIME_WAIT 的关系在这里得到了很好的解释:stackoverflow.com/questions/3757289/…

标签: java sockets connection apache-httpclient-4.x forceclose


【解决方案1】:

RequestConfig 有帮助。现在看起来所有连接都在指定限制内​​被丢弃。

       RequestConfig config= RequestConfig.custom()
                .setCircularRedirectsAllowed(false)
                .setConnectionRequestTimeout(4000)
                .setConnectTimeout(4000)
                .setMaxRedirects(0)
                .setRedirectsEnabled(false)
                .setSocketTimeout(4000)
                .setStaleConnectionCheckEnabled(true).build();
        request.setConfig(config);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多