特定の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接続プールを実装する正しい方法を実行しましたか?私は何か間違ったことをしていますか?
私の側からさらに情報が必要な場合はお知らせください。
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つが新しく作成されたことがわかります。デバッグログでそれを観察することも可能です。 ここ 参考として良い記事です。
構成が正しいようです。マルチスレッドを使用して、システムのリソースを使用してパフォーマンスを向上させることができます。
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();
HttpClient
とプーリングマネージャーを正しく設定していると思います。
私の実装には、HttpClients.custom()
を使用する代わりに、HttpClientBuilder.create()
を使用しているという点で、わずかな違いが1つありますが、メソッド呼び出しは同じです。この他のStackOverflow answer によると、これは違いを生むべきではありません。
私は以前にSpringアプリケーションでこの構成を使用しましたが、良い利点がありました。応答が十分に速く行われているので、大きなメリットが見られないのではないかと思います。私が考えることができる他の唯一のことは、潜在的にRestTemplate
が正しく構成されていないかどうかです。