Jul*_*ias 18 java tomcat httpclient
我正在为我的应用程序运行负载测试.我有两个服务器:一个用我的应用程序和一个虚拟服务器负责让我回复.
在我的虚拟服务器中,我有以下jsp代码:
<%@ page import="java.util.Random" %>
<%@ page language="java" %>
<%@ page session="false" %>
<%
String retVal = "some json string";
Thread.sleep(50);
%>
Run Code Online (Sandbox Code Playgroud)
我正在使用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" />
Run Code Online (Sandbox Code Playgroud)
我从服务器运行的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);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用50个并发线程(没有循环)运行Jmetter并得到很多例外:
org.apache.http.NoHttpResponseException The target server failed to respond
Run Code Online (Sandbox Code Playgroud)
虽然我只运行5或10个并发线程,但一切正常.
你能告诉我在我的设置中可能出现什么问题吗?据我所知,我没有看到50个并发线程请求有任何错误.
Jul*_*ias 40
我找到了问题的根本原因.
由于某种原因,连接变得无效,池不知道它.
在这种情况下,NoHttpResponseException抛出并且请求完全失败.我认为这些问题应该在HTTP客户端池层中解决,并且对我的代码是透明的,但这不是它的行为.
要解决此问题,HttpRequestRetryHandler应覆盖HTTP客户端:
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;
}
});
Run Code Online (Sandbox Code Playgroud)
此解决方案适用于HttpClient 4.5及更高版本.不推荐使用DefaultHttpClient.
HttpClientBuilder clientBuilder = HttpClients.custom();
clientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, false));
Run Code Online (Sandbox Code Playgroud)
小智 5
我在https://issues.apache.org/jira/browse/HTTPCLIENT-1610记录的缺陷中发表了评论。正如您所看到的,一旦我将非活动http连接验证前重用时间从默认的2000毫秒减少到大约100毫秒,我就不会再看到任何NoHttpResponseException。我还没有测试过找出阈值是多少在我的环境中避免使用陈旧的连接,但 100 毫秒在我的环境中绝对足够短。
| 归档时间: |
|
| 查看次数: |
34483 次 |
| 最近记录: |