web-dev-qa-db-ja.com

HTTP接続プーリングを実装する正しい方法

特定のWebサービスへのREST API呼び出し中の接続プールにApacheHTTPクライアントを使用しています。

奇妙なことに、HTTP接続プールを使用しているにもかかわらず、パフォーマンスが向上しません。

私は Apache HTTP Client を使用してWebサービスに接続していますが、コードはそこから次のようになります ドキュメント

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();

cm.setMaxTotal(200);

cm.setDefaultMaxPerRoute(20);

HttpHost Host = new HttpHost("abc.com", 80);
cm.setMaxPerRoute(new HttpRoute(Host), 50);

CloseableHttpClient httpClient = HttpClients.custom()
        .setConnectionManager(cm)
        .build();

SpringのRestTemplateを使用して、SpringのHttpClientを使用したApacheのHttpComponentsClientHttpRequestFactory実装をラップアラウンドしています。

しかし、接続プールを使用しなくても、つまり。 SpringのSimpleClientHttpRequestFactoryを使用すると、パフォーマンス上の利点は得られません。

接続が完了するまでに同じ時間がかかります。

HTTP接続プールを実装する正しい方法を実行しましたか?私は何か間違ったことをしていますか?

私の側からさらに情報が必要な場合はお知らせください。

3
ng.newbie

HTTPクライアントプールの動作に注意してください。短期間にパフォーマンスが向上する可能性があります。以下の分析を確認してください。

PoolingHttpClientConnectionManagerから javadocs

古い接続の処理はバージョン4.4で変更されました。以前は、コードは再利用する前にデフォルトですべての接続をチェックしていました。コードは、接続を最後に使用してからの経過時間が設定されたタイムアウトを超えた場合にのみ接続をチェックするようになりました。デフォルトのタイムアウトは2000msに設定されています

プールのパフォーマンスの観点からは、特定のルートへの接続は、マネージャーがデフォルトで2秒間、そのルートを「アクティブ」と見なす限り、再利用されることを意味します。
2秒間非アクティブになった後、そのルートへの接続は失効したと見なされて破棄されるため、次にそのルートが要求されたときに接続初期化ペナルティが発生します。

つまり、すぐに使用できるプールにより、最初の2秒間以降の接続のパフォーマンスが向上します。ヘビーデューティールートが最も恩恵を受けます。

簡単なテストとして、プールサイズを最大5などの小さな値に設定します。 Linuxで、5つのリクエストを送信し、そのルートへの確立された接続の数を確認します

watch "netstat -ant | grep <your route IP>"

5つの接続が表示されます。 10秒または20秒待って、同じルートに2つのリクエストを送信すると、5つの接続が閉じられ、2つが新しく作成されたことがわかります。デバッグログでそれを観察することも可能です。 ここ 参考として良い記事です。

1
Luis Muñoz

構成が正しいようです。マルチスレッドを使用して、システムのリソースを使用してパフォーマンスを向上させることができます。

    HttpGet get = new HttpGet("http://www.codersjargon.com");

    PoolingHttpClientConnectionManager connManager 
      = new PoolingHttpClientConnectionManager();

    CloseableHttpClient client = HttpClients.custom().
        setConnectionManager(connManager).build();

     MultiHttpClientConnThread thread1 = new MultiHttpClientConnThread(client, get);
     MultiHttpClientConnThread thread2 = new MultiHttpClientConnThread(client, get);
     MultiHttpClientConnThread thread3 = new MultiHttpClientConnThread(client, get); 
     thread1.start();
     thread2.start();
     thread3.start(); 
     thread1.join(); 
     thread2.join();
     thread3.join();
0
Kunal

HttpClientとプーリングマネージャーを正しく設定していると思います。

私の実装には、HttpClients.custom()を使用する代わりに、HttpClientBuilder.create()を使用しているという点で、わずかな違いが1つありますが、メソッド呼び出しは同じです。この他のStackOverflow answer によると、これは違いを生むべきではありません。

私は以前にSpringアプリケーションでこの構成を使用しましたが、良い利点がありました。応答が十分に速く行われているので、大きなメリットが見られないのではないかと思います。私が考えることができる他の唯一のことは、潜在的にRestTemplateが正しく構成されていないかどうかです。

0
Dan Goslen