并发Web请求性能问题

时间:2012-06-19 16:28:51

标签: c# httpwebrequest task-parallel-library

我正在开发一项新服务,为我们公司的多个网站属性运行QA,并遇到了一个有趣的网络并发问题。为了提高性能,我使用TPL从大量url创建HttpWebRequests,以便它们可以并行运行;但是,我似乎无法找到这个过程中的瓶颈所在。

到目前为止我的观察结果:

  • 我可以通过TPL
  • 获得最多约25-30个并行线程
  • CPU从不破坏5-6%的服务(运行在1-4核心,有和没有H / T)
  • 网卡使用情况永远不会超过2-3%
  • 整体网络流量似乎没有受到影响(其他用户不抱怨,同时运行速度测试不会显示太多影响)
  • 在我们的办公网络(15Mbps)或我们的数据中心(100 + Mbps)上运行之间的速度变化不大
  • 通过一次从多个主机下载而不是从一个主机上下载很多页面,我获得了一些性能提升。

可能的痛点:

  • CPU(内核或硬件线程数)
  • NIC
  • 允许的最大并发HttpWebRequests数
  • LAN
  • WAN
  • 路由器/交换机/负载均衡器

所以问题是:

显然现在可以在几分钟内下载整个互联网,但我很想知道在这样的情况下瓶颈在哪里以及可以采取什么措施来克服它。

作为旁注,我们目前正在使用第三方服务进行抓取,但我们在某些方面受到限制,并希望获得更大的灵活性。关于企业秘密酱或poison on the tip of the arrow ... :)的一些事情。

3 个答案:

答案 0 :(得分:7)

我强烈怀疑以下原因之一是:

  1. 您正在使用默认的连接限制。检查ServicePointManager.DefaultConnectionLimit的值。我建议你将它设置为几乎无限的值,例如1000。
  2. TPL没有启动使网络饱和所需的线程数。请注意,远程Web服务器可能会有大量延迟。等待时,您的线程不会在网络上加载负载。
  3. TPL不保证您有任何最低并行度(DOP)。这很遗憾,因为有时你真的需要在使用IO时完全控制并行度。

    我建议您手动启动固定数量的线程来执行IO,因为这是保证特定DOP的唯一方法。您需要尝试确切的值。它可以在50到500的范围内。您可以减少线程的默认堆栈大小,以便用这么多线程节省内存。

答案 1 :(得分:1)

也许您正在达到TCP连接限制,或者没有正确处理连接,在任何情况下都尝试使用JMeter之类的东西来查看可以获得的最大并发HTTP吞吐量。

答案 2 :(得分:1)

  

代码非常简单。我使用Parallel.ForEach循环   一组URL(字符串)。该操作创建了一个HttpWebRequest   然后将结果转储到ConcurrentBag中。 BTW,NCrawler似乎   有趣;我会检查一下。谢谢你的提示。

因为使用Parallel.ForEach无法控制线程数,所以我建议至少切换到ThreadPool

您可以使用QueueUserWorkItem分配工作,直到您的任务集合完全推送到工作线程或者方法返回false(池中没有线程)。

使用ThreadPool,您可以控制使用SetMaxThreads分配的最大线程数。