5

Apache HTTPClient (v4.1) を使用してアプリケーションに接続プールを実装しようとしています。問題は、並列実行されているスレッドが十分にあるにも関わらず、実行時にクライアントが常に 2 つの接続のみを確立することです。しばらくコードを変更しようとしていますが、まだ何も役に立ちません。
私はThreadSafeClientConnManager接続プールに使用しており、必要な値に MaxTotalandを設定しています。 最初に確認したいことはありますか? クライアントの作成に使用するコード セグメントは次のとおりです。DefaulMaxPerRoute



DefaultHttpClient createClient() {
    HttpParams params = new BasicHttpParams();
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, new Integer(60000));
    params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, new Integer(60000));
    params.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true);

    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("https", sf, 6443));
    registry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));

    ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, registry);
    cm.setMaxTotal(2 * maxConnections);
    cm.setDefaultMaxPerRoute(maxConnections);

    HttpHost localhost = new HttpHost("localhost");
    cm.setMaxForRoute(new HttpRoute(localhost), maxConnections);

    HttpHost sdpTargetHost = new HttpHost("webserviceIP", webservicePort, "https");
    cm.setMaxForRoute(new HttpRoute(sdpTargetHost, null, true), maxConnections);

    return new DefaultHttpClient(cm, params);
}

この関数によって返されるクライアントは、 によってRunnables管理されThreadPoolExecutorます。Runnables はクライアントを使用し、次の行があります。

HttpResponse response = httpClient.execute(httpPost, context);
HttpEntity entity = response.getEntity();
....
EntityUtils.consume(entity);

私が知っていることからEntityUtils.consume(entity)、接続が使用されなくなったことを接続マネージャーに通知し、他のスレッドが使用するために接続を解放します。したがって、接続管理は問題ないと思います。

十分な情報を提供したと思います。さらに何か追加する場合は教えてください。

ありがとう

4

2 に答える 2

8

わかった。ログを指摘してくれたオレグと、グーグルとすべてのフォーラムに感謝します。
私がしなければならなかったのは、接続マネージャーのみでクラスを定義し、HttpClient.setParams() を使用して HttpParams を設定することだけでした。したがって、コードは次のようになります。

DefaultHttpClient createClient() {
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("https", sf, 6443));

    ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(registry);
    cm.setMaxTotal(maxConnections);
    cm.setDefaultMaxPerRoute(maxConnections);

    HttpHost targetHost = new HttpHost("webserviceIP", webservicePort, "https");
    cm.setMaxForRoute(new HttpRoute(targetHost, null, true), maxConnections);

    return new DefaultHttpClient(cm);
}

クライアントを使用する直前に、

DefaultHttpClient httpClient = createClient();
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, new Integer(60000));
params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, new Integer(60000));
params.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true);
httpClient.setParams(params);

明らかにコードに論理的な違いはありませんが、これで問題は解決しました。これはおそらく HttpClient 4.1 API のある種のバグだと思います。

于 2011-10-14T12:18:16.197 に答える