43

REST URLを呼び出して、応答を返すのにかかる時間を測定しようとしています。

DefaultHttpClientからの応答を取得するために使用していREST URLます。

以下のプログラムでは、各スレッドが特定の範囲で動作します。同様に、各スレッドは間1 - 100で動作し、2番目のスレッドは間で動作します101 - 200

したがって、以下のコードでは、初めて正常に動作します。httpclient.executeしかし、2回目は、この行に2回目の例外をスローします-

java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated.
Make sure to release the connection before allocating another one.

ここで何か問題がありますか?-

以下は私のコードです-

class Task implements Runnable {

    private DefaultHttpClient httpclient = new DefaultHttpClient();
    private HttpGet httpGet;
    private HttpResponse response;

    @Override
    public void run() {

        try {

            httpGet = new HttpGet(
                    "http://localhost:8080/service/BEService/v1/get/USERID=10000/profile.ACCOUNT.SERVICE
            httpGet.getRequestLine();

            for (int userId = id; userId < id + noOfTasks; userId++) {

                    long start = System.nanoTime();

                    response = httpclient.execute(httpGet);

                    long end = System.nanoTime() - start;
                }
        } catch (Exception e) {
            LOG.error("Threw a Exception in " + getClass().getSimpleName(), e);
        }
    }
}

更新されたコード:-

私がこのようなことをしているなら-

class Task implements Runnable {

    private DefaultHttpClient httpclient = new DefaultHttpClient();
    private HttpGet httpGet;
    private HttpResponse response;

    @Override
    public void run() {

        try {

            for (int userId = id; userId < id + noOfTasks; userId++) {

                httpGet = new HttpGet("http://localhost:8080/service/BEService/v1/get/USERID=10000/profile.ACCOUNT.SERVICE");
                httpGet.getRequestLine();

                long start = System.nanoTime();

                response = httpclient.execute(httpGet);

                long end = System.nanoTime() - start;

                HttpEntity entity = response.getEntity();
                EntityUtils.consume(entity);
                }
        } catch (Exception e) {
            LOG.error("Threw a Exception in " + getClass().getSimpleName(), e);
        }
    }
}

それなら大丈夫ですか?

4

3 に答える 3

45

ここで何か問題がありますか?

はい。ドキュメントに記載されているように:

BasicClientConnectionManagerは、一度に1つの接続のみを維持する単純な接続マネージャーです。このクラスはスレッドセーフですが、1つの実行スレッドでのみ使用する必要があります。BasicClientConnectionManagerは、同じルートで後続のリクエストに接続を再利用するように努めます。ただし、持続的接続のルートが接続要求のルートと一致しない場合は、既存の接続を閉じて、指定されたルートに対して再度開きます。接続がすでに割り当てられている場合は、java.lang.IllegalStateExceptionがスローされます。

BasicClientConnectionManagerは、デフォルトでHttpClientによって使用されます。

複数のスレッド間でリクエストを処理できるプーリング接続マネージャーの使用方法については、「マルチスレッドリクエストの実行」を参照してください。

于 2013-02-14T01:31:17.690 に答える
43

DefaultHttpClientバニラ(内部で使用)を使用していると仮定するとBasicClientConnectionManager、最初に未処理/最後の応答を消費する必要があります。

EntityUtils.consumeQuietly(httpResponse.getEntity());

DefaultHttpClientそれ以外の場合は、毎回再割り当てできます。

ソース:使用後に毎回DefaultHttpClient()をシャットダウンしないようにする回避策

于 2013-04-25T09:56:48.933 に答える
1

これは、プール接続マネージャーを使用したRestTemplateの構成です。さらに5つの並行スレッドで非常にうまく機能します。

<!-- RestTemplate -->
<beans:bean id="restTemplateYT" class="org.springframework.web.client.RestTemplate">
    <beans:constructor-arg ref="httpRequestFactoryYT" />
</beans:bean>

<beans:bean id="httpRequestFactoryYT" class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"> 
    <beans:constructor-arg>
        <beans:bean class="org.apache.http.impl.client.DefaultHttpClient">
            <beans:constructor-arg>
                <beans:bean class="org.apache.http.impl.conn.PoolingClientConnectionManager"/>
            </beans:constructor-arg>
        </beans:bean>
    </beans:constructor-arg>
    <beans:property name="connectTimeout" value="5000" />
</beans:bean>

春バージョン:3.1.0

于 2014-03-12T08:16:59.530 に答える