2

我使用 HttpClient ( https://hc.apache.org/httpcomponents-client-4.5.x/index.html ) 来进行许多背靠背和并行的 http 调用。运行一段时间后,它得到这个异常:

java.net.BindException: Address already in use: connect

我试图关闭我能看到的所有东西,但我仍然必须错过一些东西,因为它仍然有那个错误。

如何正确释放连接以避免这种连接泄漏问题?

这是重现该问题的测试用例,在 Windows 上以 Java8 运行:

public void test(String url) throws Exception {
    List<Thread> threads = new ArrayList<Thread>();
    for(int t=0; t<40; t++) {
        int tt = t;
        threads.add(new Thread(() -> {
            for(int i=0; i<Integer.MAX_VALUE; i++) {
                URI metadataUri;
                try {
                    metadataUri = new URI(url);
                } catch (Exception e1) {
                    e1.printStackTrace();
                    continue;
                }

                HttpPost httpRequest = new HttpPost(metadataUri);
                httpRequest.setEntity(new ByteArrayEntity( "abc".getBytes()));
                //httpRequest.addHeader("Connection", "close");

                CloseableHttpClient httpclient = HttpClients.custom().build();
                try {
                    CloseableHttpResponse metadataResponse2 = httpclient.execute(httpRequest);
                    metadataResponse2.close();
                } catch (ClientProtocolException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        httpRequest.completed();
                        httpRequest.releaseConnection();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        httpclient.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                System.out.println("thread " + tt + " round " + i);
            }
        }));
    }

    for(Thread thread : threads) {
        thread.start();
    }
}
4

1 回答 1

-1

通常,尝试使用资源(请参阅参考资料)应处理此问题:

            try (CloseableHttpClient httpclient = HttpClients.custom().build();
                CloseableHttpResponse metadataResponse2 = httpclient.execute(httpRequest)) {
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                httpRequest.completed();
                httpRequest.releaseConnection();

            }
于 2018-11-13T16:39:31.367 回答