2015-12-27 32 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(); 
} 

但是,我似乎有瓶頸的地方。如果我嘗試做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(除初始階段開始和結束)。

我從不同的網絡,嘗試這種因此它不太可能是基於硬件的,它不應該是遠程服務器作爲其設計爲重入站負載(不是我說的數字是即使在重)

我該如何更好地描述我在做什麼?

+0

有很多的可能性,在這裏,但我的第一個猜想是,你打的是Windows的併發連接限制。另一種可能性是服務器的硬件將連接視爲潛在的DOS攻擊並對其進行限制。 –

+0

平均得分?每次請求或總數?張貼測量代碼。 – usr

+0

@usr平均執行'body' 2500次,不清楚問題 –

回答

1

執行所有工作級別在9到11秒之間的總時間。這很有道理,因爲當增加DOP(指數級)時,最終會使後端資源或網絡或其他東西飽和。

我敢打賭,如果您發佈了更低的DOP基準數量,我們會看到更高的總時間。

當你在這一點上併發請求的數量加倍時,平均完成時間加倍。

中只看每秒或所花費的總時間項測得的吞吐量。這是一個有趣的指標。每項延遲不是。

+0

是的,我做了很多測試,爲簡潔起見剪下了結果。按照你的預期,<75 dop總時間線性增長。據推測,我需要測量項目完成/秒的項目。 Servicepoint.currentconnections總是== dop,因爲排隊似乎比我的代碼更深。 –

+0

你可以發佈所有用於測量的代碼嗎?這些數字代表什麼有點不清楚。另外,你能說出你期望的結果嗎? – usr

+0

這是我的代碼,它使用AWS SES服務(我可以發送1000/s請求 - 之後我應該看到調節)https://gist.github.com/trullock/a112885d374a081aee4d –