2012-05-13 25 views
14

Tôi đang chạy thử nghiệm tải cho ứng dụng của mình. Tôi có hai máy chủ: một với ứng dụng của tôi và một máy chủ giả có trách nhiệm trả lời tôi.nhận NoHttpResponseException để kiểm tra tải

Trong máy chủ giả của tôi, tôi có mã jsp sau:

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

Tôi đang chạy các ứng dụng với tomcat7. My hồ bơi kết nối server.xml (trong cả hai máy chủ) trông giống như:

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

Mã java Tôi đang chạy từ các máy chủ là:

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

Tôi đang chạy Jmetter với 50 chủ đề cùng lúc (không có vòng lặp) và nhận được rất nhiều ngoại lệ như thế này:

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

Trong khi tôi chỉ chạy 5 hoặc 10 luồng đồng thời mọi thứ hoạt động ok.

Bạn có thể vui lòng tư vấn cho tôi những gì có thể sai trong thiết lập của tôi không? Đối với sự hiểu biết của tôi, tôi không thấy bất kỳ lỗi nào cho 50 yêu cầu luồng đồng thời.

Trả lời

30

Tôi đã tìm thấy nguyên nhân gốc rễ của vấn đề.

Vì lý do nào đó, kết nối không hợp lệ và hồ bơi không biết.

Trong trường hợp này, NoHttpResponseException bị ném và yêu cầu không thành công. Tôi nghĩ rằng các vấn đề như vậy nên được giải quyết trong lớp hồ bơi khách hàng HTTP và được minh bạch cho mã của tôi, nhưng điều này không phải là nó hoạt động.

Để giải quyết vấn đề này HttpRequestRetryHandler trong HTTP client nên được ghi đè:

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, điều này rất hữu ích! Cảm ơn rất nhiều vì đã đăng giải pháp của bạn. Đó là chính xác những gì tôi đang tìm kiếm. – trillions

+0

Giải pháp của bạn cũng đã giúp tôi. Trong trường hợp của tôi, NoHttpResponseException chỉ xảy ra đôi khi tôi đã kích hoạt anti-virus. Chống vi-rút luôn chạy một số lần quét khi yêu cầu http được gửi và đôi khi mất nhiều thời gian hơn, khiến yêu cầu không thành công. – Seigo

+0

@Seigo - Tôi hiểu đây là một chủ đề cũ, nhưng bạn đã có một executionTimeout vì trong đó các yêu cầu đã thất bại? Cài đặt nào khiến yêu cầu thất bại? –

1

tôi đăng một bình luận trong khuyết tật đăng nhập tại https://issues.apache.org/jira/browse/HTTPCLIENT-1610. Như bạn có thể thấy, khi tôi giảm thời gian xác thực-trước-tái sử dụng kết nối http không hoạt động từ 2000 mili giây mặc định xuống 100 ms, tôi không thấy bất kỳ NoHttpResponseException nữa. Tôi chưa thử nghiệm để tìm ra giá trị ngưỡng là gì trong môi trường của tôi để vô hiệu hóa bằng cách sử dụng kết nối staled nhưng 100 ms chắc chắn là đủ ngắn trong môi trường của tôi.

4

Giải pháp này dành cho phiên bản HttpClient 4.5 trở lên. DefaultHttpClient không được chấp nhận.

HttpClientBuilder clientBuilder = HttpClients.custom(); 
clientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, false)); 
Các vấn đề liên quan