【发布时间】:2014-03-18 22:10:13
【问题描述】:
我正在使用来自
的 RESTFul HttpGet 服务导入 org.apache.http.client.methods.HttpGet;
我创建了一个函数来查询另一台计算机上的服务。调用工作正常,但是我在服务上遇到“打开的文件太多”。我这边只是返回一个 500 错误,我发现了它。
我与供应商进行了交谈,他们非常坚持应该以持久的方式进行 RESTful 调用,并且我根本没有释放任何东西,并继续说问题就在我这边。
我写了一个压力函数,见下文,以帮助隔离问题。太我的知识了,我正在释放一切。我对 Java 还是很陌生,所以我只是没有看到不清楚的地方。
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
public void doStressTest()
{
String strUri = "http://<ip address>:<port>/task?vara=dataa&varb=datab";
HttpGet oRestyGet = new HttpGet();
oRestyGet.addHeader("Accept", "application/xml");
for (int iLoop = 0; iLoop < 1000; iLoop++)
{
CloseableHttpClient httpclient = HttpClients.createDefault();
try
{
oRestyGet.setURI(new URI(strUri));
try
{
CloseableHttpResponse response2 = httpclient.execute(oRestyGet);
try
{
String strResponseHeader = response2.getStatusLine().toString();
if (false == "HTTP/1.1 200 OK".equalsIgnoreCase(strResponseHeader))
return;
continue;
}
finally
{
response2.close();
}
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
httpclient.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
try
{
oRestyGet.releaseConnection();
}
catch (Exception e)
{
e.printStackTrace();
}
}
更新: 我想我添加了供应商不得不说的文字,以防万一它可能会有所帮助。我应该在下面的压力测试中补充一点,我打开了一个 HTTP GET 请求对象,对于我的“会话”来说,它是持久的并用于整个请求。
这意味着系统正在用完用户运行的 FD 过程。当有太多打开的套接字或 FD 时会发生这种情况。 通常使用 HTTP,强烈建议使用 HTTP 请求 以持久方式发送,即您有一个 HTTP 连接用于 整个会话并且不打开多个 HTTP 连接然后关闭 他们为每个请求。更多时候不是你最终会挥之不去 连接。
我正在关闭“可关闭的”CloseableHttpClient,我也不认为我只需要一个。我应该补充一点,“我”没有用完任何东西,服务是。供应商似乎说该服务和操作系统一样完美。还可以做些什么来隔离问题?
更新 2: (我把服务端的日志文件发给了供应商,他们有以下说法。僵持?)
问题似乎是剩下的连接太多了 由您的界面打开。我包含了会话中的日志文件 火狐。您可以看到我如何通过 使用浏览器进行相同的连接。
初始连接只有一行
来自 [127.0.0.1] 的 HTTP 连接...允许
后续的 GET 请求来自同一个连接。
...您的日志文件显示:HTTP connection from [192.168.20.123]...ALLOWED
对于您发出的每个 GET 请求,这些连接都不会关闭。
更新 3: 我可以访问服务生成的日志,但无法访问源。 Java 将连接和 GET 请求作为一个包发出以响应以下行:
CloseableHttpResponse response2 = httpclient.execute(oRestyGet);
我正在发出 httpclient.close(),它不生成任何日志条目,所以我怀疑服务根本没有响应。
由于我不熟悉另一端的机制,也许服务只是响应事件,问题在于 CENTOS 没有正确处理 close() 调用。无论哪种方式,使用这种方法,问题都不是我的。证明是另一回事。替代方案是某种其他可以适当释放资源的解决方案。
【问题讨论】:
-
您是否尝试过使用持久/流水线 HTTP 1.1 连接?
-
我不确定那是什么或代码将如何改变。
标签: java rest httpclient