我正在为我的应用程序运行负载测试。我有两台服务器:一台是我的应用程序,另一台是负责让我回复的虚拟服务器。
在我的虚拟服务器中,我有以下jsp代码:
<%@ page import="java.util.Random" %>
<%@ page language="java" %>
<%@ page session="false" %>
<%
String retVal = "some json string";
Thread.sleep(50);
%>
我正在使用tomcat7运行应用程序。我的server.xml连接池(在两个服务器中)看起来像:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="1500" minSpareThreads="1000" prestartminSpareThreads="true" />
<Connector port="9031" protocol="HTTP/1.1"
connectionTimeout="20000"
maxConnections="4000"
executor="tomcatThreadPool"
redirectPort="8443" />
我从服务器运行的java代码是:
HttpPost post = new HttpPost(bidderUrl);
post.setHeader("Content-Type", "application/json");
// I'm using http client with ThreadSafeClientConnManager
// total conn = 500, max conn per route = 100, timeout=500millis
HttpClient httpClient = httpClientFactory.getHttpClient();
try {
post.setEntity(new StringEntity(jsobBidRequest));
HttpResponse response = httpClient.execute(post);
...
catch (NoHttpResponseException e){
log.error(e);
}
我正在使用50个并发线程运行Jmetter(没有循环)并且得到很多例外:
org.apache.http.NoHttpResponseException The target server failed to respond
虽然我只运行5或10个并发线程,但一切正常。
你可以告诉我在我的设置中可能出现什么问题吗?据我了解,我没有看到50个并发线程请求有任何错误。
答案 0 :(得分:38)
我找到了问题的根本原因。
由于某种原因,连接无效,池无法识别。
在这种情况下,抛出NoHttpResponseException
并且请求完全失败。我认为这些问题应该在HTTP客户端池层中解决,并且对我的代码是透明的,但这不是它的行为。
要解决此问题,应覆盖HTTP客户端中的HttpRequestRetryHandler
:
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry);
...
DefaultHttpClient httpClient = new DefaultHttpClient(cm, params);
httpClient.setHttpRequestRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount,
HttpContext context) {
if (executionCount > 3) {
LOGGER.warn("Maximum tries reached for client http pool ");
return false;
}
if (exception instanceof org.apache.http.NoHttpResponseException) {
LOGGER.warn("No response from server on " + executionCount + " call");
return true;
}
return false;
}
});
答案 1 :(得分:6)
此解决方案适用于HttpClient 4.5及更高版本。不推荐使用DefaultHttpClient。
vi
答案 2 :(得分:1)
我在https://issues.apache.org/jira/browse/HTTPCLIENT-1610记录的缺陷中发表了评论。正如您所看到的,一旦我将非活动的http连接验证 - 重用前验证时间从默认的2000毫秒减少到100毫秒,我再也看不到任何NoHttpResponseException了。我还没有测试过找出什么是阈值在我的环境中使用staled连接进行无效,但在我的环境中100 ms肯定足够短。