我正在嘗試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();
}
但是,我似乎有瓶頸的地方。如果我嘗試做2500
迭代,用不同的值dop
我得到這些結果:
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~=100
以上時,您會注意到每個請求需要花費的時間(即Func<T, Task> body
花費多少時間來運行2500
次)的平均時間與DOP
幾乎呈線性增加(這些結果中有一點噪聲,但是它們是可重複的與小錯誤)。
這表明工作裏面有一個「隊列」body
在做什麼,對吧?
我已經設置
ServicePointManager.DefaultConnectionLimit = int.MaxValue;
,如果我做
servicePoint = ServicePointManager.FindServicePoint("// the url", null);
和監控
servicePoint.CurrentConnections
上的body
每次執行時,它總是等於dop
(除初始階段開始和結束)。
我從不同的網絡,嘗試這種因此它不太可能是基於硬件的,它不應該是遠程服務器作爲其設計爲重入站負載(不是我說的數字是即使在重)
我該如何更好地描述我在做什麼?
有很多的可能性,在這裏,但我的第一個猜想是,你打的是Windows的併發連接限制。另一種可能性是服務器的硬件將連接視爲潛在的DOS攻擊並對其進行限制。 –
平均得分?每次請求或總數?張貼測量代碼。 – usr
@usr平均執行'body' 2500次,不清楚問題 –