簡體   English   中英

並發Web請求性能問題

[英]Concurrent web request performance issues

我正在開發一項新服務,為我們公司的多個Web屬性運行QA,並遇到了一個有趣的網絡並發問題。 為了提高性能,我使用TPL從大量url創建HttpWebRequests,以便它們可以並行運行; 但是,我似乎無法找到過程中的瓶頸所在。

我到目前為止的觀察:

  • 我可以通過TPL獲得最多約25-30個並行線程
  • CPU永遠不會破壞5-6%的服務(運行在1-4核心,有和沒有H / T)
  • NIC使用率從未突破2-3%
  • 整體網絡流量似乎沒有受到影響(其他用戶不抱怨,速度測試運行的同時不會顯示太多影響)
  • 在辦公室網絡(15Mbps)或我們的數據中心(100 + Mbps)上運行之間的速度變化不大
  • 通過一次從多個主機下載而不是從一個主機上下載大量頁面,我獲得了一點性能提升。

可能的痛點:

  • CPU(內核或硬件線程數)
  • NIC
  • 允許的最大並發HttpWebRequests數
  • LAN
  • 廣域網
  • 路由器/交換機/負載平衡器

所以問題是:

顯然現在可以在幾分鍾內下載整個互聯網,但我很想知道在這樣的場景中瓶頸在哪里以及可以采取什么措施來克服它。

作為旁注,我們目前正在使用第三方服務進行抓取,但我們在某些方面受到限制,並希望獲得更大的靈活性。 關於企業秘密醬或箭頭尖端的毒葯 ...... :)

我強烈懷疑以下是其中一個原因:

  1. 您正在運行默認連接限制。 檢查ServicePointManager.DefaultConnectionLimit的值。 我建議你把它設置為幾乎無限的值,比如1000。
  2. TPL沒有啟動盡可能多的線程來使網絡飽和。 請注意,遠程Web服務器可能會有大量延遲。 等待時,您的線程不會在網絡上加載負載。

TPL不保證您有任何最低並行度(DOP)。 這很遺憾,因為有時你真的需要在使用IO時完全控制並行度。

我建議您手動啟動固定數量的線程來執行IO,因為這是保證特定DOP的唯一方法。 您需要嘗試確切的值。 它可以在50到500的范圍內。您可以減少線程的默認堆棧大小以節省具有該多個線程的內存。

也許你正在達到TCP連接限制,或者沒有正確處理連接,無論如何都要嘗試使用像JMeter這樣的東西來查看你可以獲得的最大並發HTTP吞吐量。

代碼非常簡單。 我使用Parallel.ForEach循環遍歷一組URL(字符串)。 該操作創建一個HttpWebRequest,然后將結果轉儲到ConcurrentBag中。 BTW,NCrawler似乎很有趣; 我會檢查一下。 謝謝你的提示。

因為使用Parallel.ForEach是不可能控制線程數的,所以我建議至少切換到一個ThreadPool

您可以使用QueueUserWorkItem分配工作,直到您的任務集合完全推送到工作線程或直到該方法返回false(池中沒有更多線程)。

使用ThreadPool您可以控制使用SetMaxThreads分配的最大線程數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM