2015-12-27 8 views
5

私はmake as many HTTP requests to a URL as possible, as quickly as possibleにしようとしています。.NETでの同時HTTPリクエストのボトルネックを特定する方法は?

私はこのコードを使用して最大並列度を調整することができますので、一度にたくさんのブロックを生成してメモリをオーバーフローさせません。Tasks

public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body) 
    { 
     return Task.WhenAll(
      from partition in Partitioner.Create(source).GetPartitions(dop) 
      select Task.Run(async delegate { 
       using (partition) 
        while (partition.MoveNext()) 
         await body(partition.Current); 
      })); 
    } 

これは正常に動作しているようです。

body()は、本質的に沸く:

async Task Body() 
{ 
    var r = WebRequest.Create("// the url"); 
    await r.GetResponseAsync(); 
} 

しかし、私はどこかにボトルネックを持っているようです。

DOP: 50 
Total Time: 00:00:14.4801781 
Average (ms): 246.6088 
StDev: 84.1327983759009 

DOP: 75 
Total Time: 00:00:09.8089530 
Average (ms): 265.758 
StDev: 110.22912244956 

DOP: 100 
Total Time: 00:00:11.9899793 
Average (ms): 344.9168 
StDev: 173.281468939295 

DOP: 200 
Total Time: 00:00:09.1512825 
Average (ms): 627.0492 
StDev: 572.616238312676 

DOP: 500 
Total Time: 00:00:09.3556978 
Average (ms): 1361.5328 
StDev: 1798.70589239157 

DOP: 750 
Total Time: 00:00:12.6076035 
Average (ms): 2009.058 
Normal Total: 5022646 
StDev: 2348.20874093199 


DOP: 1000 
Total Time: 00:00:11.4721195 
Average (ms): 2453.782 
StDev: 2481.56238190299 

DOP: 2000 
Total: 00:00:11.6039888 
Average (ms): 4100.5536 
StDev: 2459.36983911063 

dop=50がボトルネック未満であることを示唆しているように見える:私はdopのためにさまざまな値を使用して、試してみて、2500繰り返しを行う場合、私はこれらの結果を取得します。しかし、あなたがdop~=100を超えると、が実行するのに要する時間の平均(つまり、2500時間の平均)はDOPでほぼ直線的に増加します(これらの結果にノイズはほとんどありませんが、小さな誤差で)。

これは、「キュー」は仕事bodyの内側に存在することを示唆しているが、右、しているのですか?

を除いて(私はすでに

ServicePointManager.DefaultConnectionLimit = int.MaxValue; 

を設定していると私は

servicePoint = ServicePointManager.FindServicePoint("// the url", null); 

を行うとbodyの各実行に

servicePoint.CurrentConnections 

を監視する場合、dopにその常に等しいです最初のランプアップとテールオフ)。

私はこれをさまざまなネットワークから試しました。そのため、ハードウェアベースである可能性は低く、重いインバウンド負荷用に設計されたリモートサーバであってはいけません。 )

私が行っていることをどのようにプロファイルすることができますか?

+0

ここにはたくさんの可能性がありますが、私の最初の推測は、Windowsの同時接続制限を打つことです。もう1つの可能性は、サーバのハードウェアがあなたの接続を潜在的なDOS攻撃として扱い、それらを抑制することです。 –

+0

平均何ですか?要求ごとにまたは合計で?測定コードを記入してください。 – usr

+0

@usr 'body'を2500回実行する平均時間は、質問を明確にしてください –

答えて

1

9〜11秒の作業レベルをすべて実行するための合計時間。 DOPを増やす(指数関数的に)と、最終的にバックエンドのリソースやネットワークなどが飽和するため、意味があります。

私はあなたが低DOPのベンチマーク番号を掲示していた場合、我々は高い全回を参照してくださいでしょう賭けます。

あなたは、この時点での同時要求の平均完了時間の倍の数を2倍。毎秒アイテムまたは総時間で測定されたスループットで

ルック。それは興味深い指標です。アイテムごとの待ち時間はありません。

+0

ええ、私は多くのテストを行い、簡潔さのために結果をカットしました。 <75ドッドは、あなたが期待するように、総時間が直線的に増加するのを見ます。おそらくアイテム/ sのアイテムを測定する必要があります。 Servicepoint.currentconnectionsは常に== dopです。キューイングは自分のコードよりも深く見えるからです。 –

+0

これを測定するために使用されたすべてのコードを投稿できますか?これらの数字が何を表しているかは少し不明です。また、あなたが期待した結果を言うことができますか? – usr

+0

私のコードは、AWS SESサービスを使用しています(1000/sリクエストを送信することが許可されています - それ以降はスロットリングが必要です)。https://gist.github.com/trullock/a112885d374a081aee4d –

関連する問題