java - 如何保持多个 Java HttpConnections 打开到同一个目的地

标签 java http servlets tcpclient httpurlconnection

我们经常使用 HttpURLConnection API 向同一提供商调用 REST API(一种聚合用例)。我们希望保持一个包含 5 个连接的池始终对提供商主机开放(始终使用相同的 IP)。

什么是正确的解决方案?这是我们尝试过的:


System.setProperty("http.maxConnections", 5);  // set globally only once
...
// everytime we need a connection, we use the following
HttpURLConnection conn = (HttpURLConnection) (new URL(url)).openConnection();
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.setDoOutput(false);
conn.setUseCaches(true);
...
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
...

此时我们读取输入流,直到 BufferedReader 不再返回字节。如果我们想重用与提供者的底层连接,在那之后我们该怎么办?我们的印象是,如果输入流被完全读取,连接就会被添加回池中。

它已经以这种方式工作了几个星期,但今天它停止工作并产生以下异常:java.net.SocketException: Too many open files

我们发现许多套接字处于 CLOSE_WAIT 状态(通过运行 lsof): java 1814 root 97u IPv6 844702 TCP colinux:58517->123.123.254.205:www (CLOSE_WAIT)

conn.getInputStream().close() 或 conn.disconnect() 不会完全关闭连接并将其从池中删除吗?

最佳答案

我们在 Java 5 上也遇到了这个问题,我们的解决方案是切换到具有池连接管理器的 Apache HttpClient。

Sun 的 HTTP URL 处理程序的 keepalive 实现有很多错误。没有关闭空闲连接的维护线程。

keepalive 的另一个更大的问题是你需要删除响应。否则,连接也将被孤立。大多数人没有正确处理错误流。有关如何正确读取错误响应的示例,请参阅我对此问题的回答,

HttpURLConnection.getResponseCode() returns -1 on second invocation

关于java - 如何保持多个 Java HttpConnections 打开到同一个目的地,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1936872/

相关文章:

java - String.split() 后出现 ArrayIndexOutOfBoundsException

java - 在 HTTP 请求中设置 UTC 时间

javascript - 如何获取 Javascript Last-Modified 日期

http - URL 真的可以被认为是 HTTP 响应的唯一键吗? - 第2部分

java - java中基于 token 的登录和身份验证

java - 多个 Servlet 映射

java - 如何强制 CFHTTP 不对查询参数进行编码?

java - 无法将两个矩阵相乘(double[][] 数组)

java - 如何从Java中的桌面调用文件?

java - 服务器推送好还是客户端推送好?