为什么执行POST时HttpClient会抛出SocketTimeOutException?

5
我可以帮您进行翻译。以下是与以下代码类似的代码:
try {
    HttpPost post = new HttpPost(httpsUrl);
    setHeaders(post);

    HttpEntity entity = new StringEntity(request, "UTF-8");

    post.setEntity(entity);

    HttpResponse response = httpclient.execute(post);
    String result = EntityReader.readContent(response.getEntity());
    checkAnswer(result);
    return result;

} catch (Exception e) {
    throw new ZapException("Error executing the http post request: "+e.getMessage(), e);
}

它使用一个可能已经被使用过的httpclient实例通过POST将request的内容发送到服务器(由于我们向同一服务器发送了相当多的请求,因此开启了持久连接...)。
有时候会出现SocketTimeoutException,错误消息为“读取超时”。我们不清楚为什么它只在某些时候失败,而大多数情况下则没有问题。是什么原因导致这种情况?

当我使用Tomcat 7向Solr发送多个请求时,我遇到了类似的问题。你是向哪里发送请求的?你的服务器细节是什么,因为错误就是从那里产生的。 - Steve Casey
我认为那是Jetty 6。但那是相当久以前的事了... - kungfoo
1个回答

3
在接下来的内容中,我假设您正在使用Apache Commons HttpClient (org.apache.commons.httpclient.HttpClient)。也许您会因为HttpClient实例通信的主机响应时间过长而抛出SocketTimeoutException,从而触发HttpClient的取消例程。您可以使用以下方法增加连接超时和套接字超时。
HttpConnectionParams params = httpclient.getHttpConnectionManager().getParams();
params.setConnectionTimeout(20000);
params.setSoTimeout(15000);

此外,如果您尽管增加了超时限制仍然遇到超时问题,处理SocketTimeoutException异常是一个好的做法 - 例如通过第二次和第三次重试连接来优雅地处理。

2
HttpClient默认行为不是会自动重试三次吗? - Rafael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接