2012-05-13 14 views
14

Uygulamam için yük testleri çalıştırıyorum. İki sunucum var: biri uygulamamla ve yanıtları almaktan sorumlu olan bir sahte sunucu.Yük testi için NoHttpResponseException alın

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

Ben tomcat7 uygulamayı çalıştırıyorum: Benim kukla sunucusunda

Aşağıdaki jsp kodu var.

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

Ben sunucularından koşuyorum java kodu: Ben 50 eşzamanlı konuları ile Jmetter (koşuyorum

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

gibi (her iki sunucularda) Benim server.xml bağlantı havuzu görünüyor ve) bir döngü olmadan böyle istisnalar çok olsun:

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

koşuyorum ederken sadece 5 veya 10 eşzamanlı konuları herşey yolunda çalışır.

Kurulumumda neyin yanlış olabileceğini bana bildirir misiniz? Anlayışım için, 50 eş zamanlı iş parçacığı isteği için herhangi bir hata göremiyorum.

cevap

30

Sorunun kök nedenini buldum.

Bazı nedenlerden dolayı bağlantı geçersiz hale gelir ve havuz bunun farkında değildir.

Bu durumda NoHttpResponseException atılır ve istek yalnızca başarısız olur. Bu tür sorunların HTTP istemci havuzu katmanında çözülmesini ve benim koduma saydam olması gerektiğini düşündüm, ancak bu eylemde olduğu gibi değil.

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, bu çok faydalıdır! Çözümünüzü yayınladığınız için çok teşekkürler. Tam olarak aradığım şey bu. – trillions

+0

Çözümünüz de bana yardımcı oldu. Benim durumumda, NoHttpResponseException sadece anti-virüs etkinleştirildiğinde ara sıra meydana geldi. Anti-virüs her zaman bir http isteği gönderildiğinde biraz tarama yapar ve zaman zaman biraz daha uzun sürer ve bu da talebinin başarısız olmasına neden olur. – Seigo

+0

@Seigo - Bunun eski bir ileti dizisi olduğunu anlıyorum, ancak isteklerin başarısız olduğu için bir yürütme Sürümü'nü aldınız mı? Hangi ayar isteklerin başarısız olmasına neden oldu? –

1

Ben https://issues.apache.org/jira/browse/HTTPCLIENT-1610 de açmış kusurlarında bir yorum yayınladı:

bu sorunun geçersiz kılınmış HTTP istemcisi HttpRequestRetryHandler çözmek için. Gördüğünüz gibi, etkin olmayan http bağlantı validate-yeniden-kullanım süresini varsayılan 2000 ms'den 100 ms'ye düşürdüğümde, artık hiçbir NoHttpResponseException göremiyorum. Eşik değerinin ne olduğunu bulmak için test etmedim. çevremde stal bağlantılı bağlantıyı geçersiz kılacak ama 100 ms kesinlikle çevremde yeterince kısa.

4

Bu çözüm, HttpClient 4.5 ve sonraki sürümleri içindir. DefaultHttpClient kullanımdan kaldırıldı.

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