1

サーバーへの同時TCP接続を100回行うC#NUnitテストを作成しています。テストの目的は、サーバーにストレスをかけることです。

これを行うために、テストは100個の新しいスレッドを作成し、それらをループして呼び出しthread.Start()、次にそれらを再度ループしてを呼び出しますthread.Join()

各スレッドは、TCP接続を確立し、いくつかのデータを要求し、受信したデータがnullでないかどうかを確認してから、完了までにかかった時間を出力するメソッドを実行します。

私が気付いたのは、100の接続では、後でコンソールに書き込むスレッドの場合、各スレッドがタスクを完了するのに必要な時間が2秒から50秒に増加することです。ただし、への各呼び出しの間に2秒の遅延を導入するとthread.Start()、必要な時間はスレッドごとに2秒になります。

遅延なしのシナリオでは、必要な時間の増加は、単体テストを実行しているマシン(つまり、開発ボックス)の問題が原因である可能性があるのではないかと思います。たとえば、.NET / Windows 7では、リソースが原因で100個のTCP接続を次々に作成できない可能性があります。

TCPプログラミングの知識を持っている人がコメントしてくれませんか?開発ボックスがボトルネックであるかどうかを判断するために使用できるツールは何ですか?

目標は、結果がサーバーの実際に有効なストレステスト結果であるかどうかを知ることです。

public void ServerStressTest()
{
    const int NUMBER_OF_REQUESTS = 10;
    const int DELAY_BETWEEN_REQUESTS = 0;
    var threads = new System.Collections.Generic.List<Thread>();
    var urls = new StaticDataUrls();

    Console.WriteLine(string.Format("Requesting static data from the server {0} times with {1} seconds delay between subsequent requests...", NUMBER_OF_REQUESTS, DELAY_BETWEEN_REQUESTS));

    for (int i = 0; i < NUMBER_OF_REQUESTS; i++)
    {
        var callNumber = i; // prevent access to modified closure
        threads.Add(new Thread(() => FetchStaticData(urls, callNumber)));
    }

    threads.Apply(t =>
                      {
                          Thread.Sleep(DELAY_BETWEEN_REQUESTS * 1000); 
                          t.Start();
                      });

    threads.Apply(t => t.Join());
}

private void FetchStaticData(StaticDataUrls urls, int callNumber)
{
    var restAdapter = new RestAdapter(true, new Log4NetLogger(GetType()));

    var stopwatch = Stopwatch.StartNew();
    var underlyingResults = restAdapter.Get(urls.UnderlyingUrl);
    var clientResults = restAdapter.Get(urls.ClientUrl);
    stopwatch.Stop();

    var missingData = new System.Collections.Generic.List<string>();
    if(string.IsNullOrEmpty(clientResults.ResponseData)) missingData.Add("client");
    if(string.IsNullOrEmpty(underlyingResults.ResponseData)) missingData.Add("underlying");

    Console.WriteLine(missingData.Count > 0
                          ? string.Format("Call {0}: No {1} data received in {2} seconds", callNumber, string.Join(", ", missingData.ToArray()), stopwatch.Elapsed.Seconds)
                          : string.Format("Call {0}: Completed with all data in {1} seconds", callNumber, stopwatch.Elapsed.Seconds));
}
4

1 に答える 1

1

発生する可能性が高いのは、新しいスレッドの開始に遅延がない場合、CPU /ネットワークの負荷が増加し、各スレッドが他のスレッドとCPU時間を共有しているため、各スレッドに時間がかかることです。

ただし、各スレッドを2秒間隔で開始すると、基本的に、新しいスレッドが開始する前に各スレッドを完了することができます。

あまりにも多くのTCP接続を開こうとした場合に、.NETランタイムでなんらかの例外が発生しなかったとしたら、私は驚きます。

遅延なしの方法は、まともなストレステストです。

于 2012-08-31T17:18:24.617 に答える