2012-05-13 16 views
14

어플리케이션에 대한로드 테스트를 실행하고 있습니다. 두 개의 서버가 있습니다 : 하나는 내 응용 프로그램이고 다른 하나는 응답을받을 책임이있는 더미 서버입니다.로드 테스트 NoHttpResponseException을 받으십시오.

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

내가 tomcat7로 응용 프로그램을 실행 해요 : 내 더미 서버에서

나는 다음과 같은 JSP 코드가 있습니다.

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

I는 서버에서 실행하고있어 자바 코드는 다음과 같습니다 : 나는 50 개 동시 스레드 Jmetter을 (실행 해요

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

처럼 (두 서버 모두에서) 내 server.xml을 연결 풀 보인다 루프없이) 다음과 같은 많은 예외가 발생합니다.

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

5 개 또는 10 개의 동시 스레드를 실행하는 동안 모든 것이 정상적으로 작동합니다.

내 설정에서 잘못 될 수있는 점을 알려주세요. 내 이해를 위해, 나는 50 동시 스레드 요청에 대한 오류를 볼 수 없습니다.

답변

30

문제의 근본 원인을 발견했습니다.

어떤 이유로 연결이 무효화되고 풀에서 인식하지 못합니다.

이 경우 NoHttpResponseException이 발생하고 요청이 단순히 실패합니다. 나는 그러한 문제가 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; 
     } 
    }); 
+1

줄리아, 이것은 매우 유용합니다! 솔루션을 게시 해 주셔서 감사합니다. 그것은 정확히 내가 뭘 찾고 있어요. – trillions

+0

당신의 솔루션 또한 도움이되었습니다. 제 경우에는 안티 바이러스가 활성화되었을 때만 NoHttpResponseException이 가끔 발생했습니다. 안티 바이러스는 http 요청이 전송 될 때 항상 검사를 실행하며, 때로는 더 오랜 시간이 걸려 요청이 실패합니다. – Seigo

+0

@ Seigo - 이건 오래된 스레드 인 줄 알았는데 요청이 실패했기 때문에 executionTimeout을 가졌습니까? 어떤 설정으로 인해 요청이 실패 했습니까? –

1

내가 https://issues.apache.org/jira/browse/HTTPCLIENT-1610에 기록 된 결함에 코멘트를 게시 :

이 문제를 오버라이드 (override) 할 필요가 HTTP 클라이언트에서 HttpRequestRetryHandler 해결합니다. 보시다시피, 비활성화 된 HTTP 연결 유효성 검사 전 재사용 시간을 기본 2000ms에서 100ms로 줄이면 더 이상 NoHttpResponseException이 표시되지 않습니다. 임계 값이 무엇인지 알아보기 위해 테스트하지 않았습니다. 내 환경에서 staled 연결을 사용하여 무효화하는 것이지만 100 밀리 초는 내 환경에서 충분히 짧습니다.

4

이 솔루션은 HttpClient 4.5 이상 버전 용입니다. DefaultHttpClient는 더 이상 사용되지 않습니다.

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