26

アプリケーションの負荷テストを実行しています。私には2つのサーバーがあります。1つはアプリケーション用で、もう1つは応答を取得するためのダミーサーバーです。

私のダミーサーバーには、次のjspコードがあります。

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

tomcat7でアプリケーションを実行しています。私のserver.xml接続プール(両方のサーバー)は次のようになります:

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

サーバーから実行しているJavaコードは次のとおりです。

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

私は50の同時スレッド(ループなし)でJmetterを実行しており、次のような多くの例外が発生します。

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

5つまたは10の同時スレッドを実行している間は、すべて問題なく動作します。

私のセットアップで何が間違っている可能性があるか教えていただけますか?私の理解では、50の同時スレッド要求に対してエラーは表示されません。

4

3 に答える 3

49

問題の根本的な原因を見つけました。

何らかの理由で接続が無効になり、プールはそれを認識しません。

この場合、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;
      }
   }); 
于 2012-05-21T06:48:54.983 に答える
8

このソリューションは、バージョンHttpClient4.5以降用です。DefaultHttpClientは非推奨です。

HttpClientBuilder clientBuilder = HttpClients.custom();
clientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, false));
于 2017-01-19T16:24:34.463 に答える
4

https://issues.apache.org/jira/browse/HTTPCLIENT-1610に記録された欠陥にコメントを投稿しました。ご覧のとおり、非アクティブなhttp接続の再利用前の検証時間をデフォルトの2000ミリ秒から100ミリ秒程度に短縮すると、NoHttpResponseExceptionは表示されなくなります。しきい値を確認するためのテストは行っていません。私の環境では、接続の停止を使用して無効にすることができますが、100ミリ秒は私の環境では間違いなく十分に短いです。

于 2016-12-14T15:34:46.227 に答える