2012-05-13 16 views
14

Sono in esecuzione test di carico per la mia applicazione. Ho due server: uno con la mia applicazione e un server fittizio che è responsabile per ottenere le mie risposte.ottenere NoHttpResponseException per il test di carico

Nel mio server fittizio Ho il seguente codice JSP:

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

sto correndo l'applicazione con tomcat7. Il mio pool di connessioni server.xml (in entrambi i server) si presenta come:

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

il codice Java sto correndo dai server è:

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

Io corro Jmetter con 50 thread concorrenti (senza un anello) e ottenere un sacco di eccezioni in questo modo:

org.apache.http.NoHttpResponseException The target server failed to respond 

Mentre io corro solo 5 o 10 thread simultanei tutto funziona bene.

Potresti per favore segnalarmi cosa potrebbe esserci di sbagliato nel mio setup? Per quanto ne so, non vedo errori per le 50 richieste di thread simultanee.

risposta

30

Ho trovato la causa principale del problema.

Per qualche motivo la connessione diventa non valida e il pool non ne è a conoscenza.

In questo caso viene generato il numero NoHttpResponseException e la richiesta semplicemente fallisce. Ho pensato che tali problemi dovessero essere risolti nel livello del pool di client HTTP ed essere trasparenti al mio codice, ma questo non è come agisce.

per risolvere questo problema il HttpRequestRetryHandler nel client HTTP dovrebbe essere sovrascritto:

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

Julias, questo è molto utile! Grazie mille per aver pubblicato la tua soluzione. È esattamente quello che sto cercando. – trillions

+0

Anche la tua soluzione mi ha aiutato. Nel mio caso, la NoHttpResponseException si verificava solo occasionalmente quando avevo attivato l'anti-virus. L'anti-virus esegue sempre delle scansioni quando viene inviata una richiesta http e occasionalmente richiede un po 'più di tempo, causando il fallimento della richiesta. – Seigo

+0

@Seigo - Capisco che questo è un thread vecchio, ma hai avuto un timeout di esecuzione a causa del quale le richieste stavano fallendo? Quale impostazione ha causato il fallimento delle richieste? –

1

ho pubblicato un commento nel difetto connesso a https://issues.apache.org/jira/browse/HTTPCLIENT-1610. Come potete vedere, una volta che riduco la durata della connessione http inattiva prima del riutilizzo dal 2000 ms predefinito a qualcosa come 100 ms, non vedo più NoHttpResponseException. Non ho testato per scoprire qual è il valore di soglia nel mio ambiente per annullare l'uso della connessione staled ma 100 ms è decisamente abbastanza breve nel mio ambiente.

4

Questa soluzione è per la versione HttpClient 4.5 e successive. DefaultHttpClient è deprecato.

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