получить NoHttpResponseException для нагрузочного тестирования

Я провожу нагрузочные тесты для своего приложения. У меня есть два сервера: один с моим приложением и фиктивный сервер, который отвечает за получение ответов.

На моем фиктивном сервере у меня есть следующий jsp код:

<code><%@ page import="java.util.Random" %>
<%@ page language="java" %>
<%@ page session="false" %>
<%
   String retVal = "some json string";
   Thread.sleep(50);
%>
</code>

Я запускаю приложение с tomcat7. Мой пул соединений server.xml (на обоих серверах) выглядит так:

<code><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" />
</code>

Явский код, который я запускаю с серверов:

<code> 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);
    }
</code>

Я запускаю Jmetter с 50 одновременными потоками (без цикла) и получаю множество исключений, подобных этому:

<code>org.apache.http.NoHttpResponseException The target server failed to respond 
</code>

Пока у меня запущено всего 5 или 10 одновременных потоков, все работает нормально.

Не могли бы вы посоветовать мне, что может быть не так в моей настройке? Насколько я понимаю, я не вижу никаких ошибок для 50 одновременных запросов потока.

Ответы на вопрос(3)

Решение Вопроса

По какой-то причине соединение становится недействительным, и пул не знает об этом.

В этом случае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;
      }
   }); 
 10 окт. 2012 г., 02:49
Юлия, это очень полезно! Большое спасибо за публикацию вашего решения. Это именно то, что я ищу.
 23 февр. 2015 г., 20:40
@AndyDufresne, я разрабатывал настольное приложение для Windows и некоторых пользователей & apos; Первые запросы всегда терпели неудачу из-за некоторой проверки, сделанной антивирусом. После добавления RetryHandler мой диагноз подтвердился. Это было давно, и это то, что я помню сейчас, надеюсь, это поможет.
 23 апр. 2013 г., 22:30
Ваше решение также помогло мне. В моем случае исключение NoHttpResponseException происходило только иногда, когда у меня был активирован антивирус. Антивирус всегда запускает некоторую проверку при отправке http-запроса, и иногда это занимает немного больше времени, что приводит к сбою запроса.
 09 февр. 2015 г., 13:21
@Seigo - я понимаю, что это старый поток, но у вас был executeTimeout, из-за которого запросы не выполнялись? Какой параметр вызвал сбой запросов?
 19 апр. 2016 г., 15:36
Это решение сработало для меня, но, мне кажется, вам лучше использовать новый StandardHttpRequestRetryHandler (3, true) вместо собственной реализации обработчика повторов. StandardHttpRequestRetryHandler повторяет только те вызовы, для которых метод http идемпотентен

л.

HttpClientBuilder clientBuilder = HttpClients.custom();
clientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, false));

https://issues.apache.org/jira/browse/HTTPCLIENT-1610, Как вы можете видеть, после того как я сократил время проверки неактивного http-соединения с 2000 мс по умолчанию до примерно 100 мс, я больше не вижу никаких исключений NoHttpResponseException. Я не проверял, чтобы определить пороговое значение в моем окружении, чтобы отказаться от использования устаревшего соединения, но 100 мс определенно достаточно коротка в моем окружении.

Ваш ответ на вопрос