多线程网络爬虫线程限制

时间:2014-10-06 08:09:44

标签: c# multithreading

我可以访问用.NET C#编写的应用程序,它连接(主要使用“原始”http请求,部分Web服务和xml请求,仍然通过http)到许多外部系统并更新其中的一些内容。

在给定时间可能有很多工作排队,而提高吞吐量的天真方法是增加线程数。它背后的逻辑是:由于我们大多数时间都在等待网络回复,我们可以同时等待更多的网络回复。 cpu和ram似乎没有达到极限。

仍然创建大约300个线程使得一切都比较低的线程数慢。

我想知道它是操作系统限制(Windows Server 2012 r2),.NET(4.5)限制还是其他什么?我怎样才能诊断出瓶颈在哪里? (正如我所说的cpu和ram似乎不是问题)

我知道外部系统可能会过载并降低整体性能,但我们假设这可以忽略不计。

3 个答案:

答案 0 :(得分:5)

创建一个线程需要一些 CPU和RAM,300个线程创建为每个线程分配至少1 MB加上堆栈分配以及其他一些东西。

你应该使用线程池。池中的线程已经创建,正在等待为您服务。

如果长时间等待网络响应,您可以使用asynchronous IO algorythm,它不需要很多线程。

答案 1 :(得分:3)

最可能的问题是:

  1. 作为评论中指示的AgentFire,ServicePointManager.DefaultConnectionLimit属性将限制您可以拥有到单个域的并发连接数。默认值为2.如果您尝试在多个请求中从单个服务器获取大量数据,那么您将受到限制。如果需要,可以增加此值。但请注意,服务器可能会将您的多个连接视为企图拒绝服务攻击,并阻止或限制您。
  2. .NET HTTP堆栈中的某些似乎是单线程的。我怀疑它是在DNS解析中。我发现使用多个线程很容易保持每秒15到20个请求的吞吐量。这当然取决于您下载的文档的大小以及您正在与之通信的服务器的响应能力,但我运行爬虫的经验是天真的方法(每个线程使用{{1我最终平均每秒15到20个请求。
  3. 在#2的情况下,我怀疑是DNS,因为我运行了一个单独的测试,在该测试中我对我正在使用的域进行了DNS解析,而我的平均值是每个请求50到60毫秒。大多数回来真快,但有些需要几秒钟。此外,当我在本地网络上放置一个大型DNS缓存时,我的吞吐量显着增加。

    CPU和内存不会成为您的限制因素。除DNS解析外,您还必须考虑连接速度。如果您有10个并发连接,每个连接都以1 Mb /秒的速率从服务器下载,那么您将要使10 Mb / s的Internet连接饱和。您应该查看您正在使用的网络带宽。

    根据我的经验,这些是最大的瓶颈。你应该调查每一个,看看是否有任何一个或多个是你认为表现不佳的原因。

答案 2 :(得分:2)

当你有足够的RAM时,300个线程根本不是问题。大多数人本能地嘲笑这种架构。同样的人从未测试过它们。它工作得很好。操作系统引起的性能问题在我的Win7系统上的10000+范围内开始变得重要。操作系统变得不稳定。

在你的情况下,我仍然更喜欢异步IO,因为你的线程数非常高。 尽管如此,同步IO可能不是您的问题。

  

如何诊断瓶颈在哪里?

检查所有可能的瓶颈。 CPU和RAM都不是一个。检查网络利用率。你在用磁盘吗?您确定您的外部服务没有超出范围吗?它们可能具有并发限制。

我假设您已经提高了.NET连接限制?!找出实际同时进行的请求数量。我是这样做的:

  1. 暂停调试器并确保当前许多线程都在.NET Web堆栈中。
  2. 查看打开的TCP连接数(Process Explorer或TcpView.exe)
  3. 使用Fiddler并查看有多少请求似乎同时处于活动状态。
相关问题