複数のスレッドにまたがるリクエストをヒットして、Web サイトのパフォーマンスをテストしようとしています。各スレッドはn回実行されます。(for ループ内)
しかし、私は問題に直面しています。具体的には、内部例外を伴う WebException (「リモート サーバーに接続できません」):
システムに十分なバッファ領域がないか、キューがいっぱいだったため、ソケットに対する操作を実行できませんでした 127.0.0.1:52395
スレッドあたり 500 回の反復で 100 スレッドを実行しようとしています。
最初はHttpWebRequest
System.Net で使用して、サーバーへの GET 要求を作成していました。現在WebClient
、各反復が新しいソケットを使用していると想定して使用しています(したがって、短期間で100 * 500ソケット)。WebClient (スレッドごとに 1 回インスタンス化される) は 1 つのソケットしか使用しないと想定しました。
一度に 50,000 個のソケットを開く必要はありません。GET 要求を送信し、応答を受信し、ソケットを閉じて、次のループ反復で使用できるように解放したいからです。問題になることは理解しています
ただし、WebClient を使用しても、多数のソケットが要求されており、その結果、多数のソケットがTIME_WAIT
モードになっています (netstat を使用して確認)。これにより、他のアプリケーション (インターネット ブラウザーなど) がハングし、機能が停止します。
ソケットが最終的にこの TIME_WAIT 状態を終了するように見えるため、反復回数やスレッド数を減らしてテストを実行できます。ただし、Web サーバーの機能を十分にテストしていないため、これは解決策ではありません。
質問:
TIME_WAIT 状態とソケットの枯渇を防ぐために、各スレッドの反復後に (クライアント側から) 明示的にソケットを閉じるにはどうすればよいですか?
コード:
HttpRequest をラップするクラス
編集: WebClient を using でラップしたため、反復ごとに新しいインスタンスがインスタンス化され、使用され、破棄されます。問題はまだ解決していません。
public sealed class HttpGetTest : ITest {
private readonly string m_url;
public HttpGetTest( string url ) {
m_url = url;
}
void ITest.Execute() {
using (WebClient webClient = new WebClient()){
using( Stream stream = webClient.OpenRead( m_url ) ) {
}
}
}
}
新しいスレッドを作成する ThreadWrapperClass の部分:
public void Execute() {
Action Hammer = () => {
for( int i = 1; i <= m_iterations; i++ ) {
//Where m_test is an ITest injected through constructor
m_test.Execute();
}
};
ThreadStart work = delegate {
Hammer();
};
Thread thread = new Thread( work );
thread.Start();
}