多线程网络爬网程序线程限制
本文关键字:线程 程序 网络 多线程 | 更新日期: 2023-09-27 18:25:36
我可以访问一个用.NET C#编写的应用程序,该应用程序(主要使用"原始"http请求,部分使用web服务和xml请求,仍然通过http)连接到许多外部系统,并更新其中的一些内容。
在给定的时间可能会有很多工作排队,而增加吞吐量的简单方法是增加线程数。其背后的逻辑是:由于大多数时间我们都在等待网络回复,我们可以同时等待更多的网络回复。cpu和ram似乎并没有突破它们的极限。
仍然创建大约300个线程会使一切工作速度比线程数较低时慢。
我想知道这是操作系统限制(windows server 2012 r2)、.NET(4.5)限制还是其他限制?如何诊断瓶颈在哪里?(正如我所说,cpu和ram似乎不是问题所在)
我知道外部系统可能会过载并降低整体性能,但我们假设这是可以忽略不计的。
创建一个线程需要一些CPU和RAM,300个线程创建为每个线程分配至少1MB,再加上堆栈分配和一些其他东西。
为此,您应该使用线程池。池中的线程已经创建,正在等待为您提供服务。
在长时间等待网络响应的情况下,您可以使用异步IO算法,它不需要很多线程。
最可能的问题是:
- 正如AgentFire在注释中指出的那样,ServicePointManager.DefaultConnectionLimit属性将限制与单个域的并发连接数。默认值为2。如果您试图在多个请求中从单个服务器获取大量数据,那么您将受到限制。如果需要,您可以增加此值。不过,请注意,服务器可能会将您的多个连接视为试图拒绝服务攻击,并阻止或阻止您
- 看起来.NET HTTP堆栈中的东西是单线程的。我怀疑它在DNS解析中。我发现使用多个线程可以很容易地保持每秒15到20个请求的吞吐量。当然,这取决于您正在下载的文档的大小和与之通信的服务器的响应能力,但我运行爬网程序的经验是,在最简单的方法(使用
HttpWebRequest
,每个线程一个请求)中,我平均每秒收到15到20个请求
在#2的情况下,我怀疑DNS,因为我运行了一个单独的测试,在该测试中,我对正在处理的域进行了DNS解析,平均每个请求50到60毫秒。大多数人很快就回来了,但有些人需要几秒钟的时间。此外,当我在本地网络上放置一个大的DNS缓存时,我的吞吐量显著增加。
CPU和内存不会成为你的限制因素。除了DNS解析,您还必须考虑您的连接速度。如果你有10个并发连接,每个连接都以1Mb/s的速率从服务器下载,那么你将使10Mb/s的互联网连接饱和。您应该查看您正在使用的网络带宽。
根据我的经验,这些是最大的瓶颈。你应该调查每一个,看看是否有一个或多个是你表现不佳的原因。
当您有足够的RAM可用时,300个线程根本不是问题。大多数人本能地嘲笑这样的建筑。同样的人从来没有自己测试过。它工作得很好。在我的Win7系统上,操作系统导致的性能问题在10000+范围内开始变得重要。操作系统的使用变得不稳定。
在您的情况下,我仍然更喜欢异步IO,因为您的线程数相当高不过,同步IO可能不是你的问题
如何诊断瓶颈在哪里?
检查所有可能的瓶颈。CPU和RAM都不是一体的。检查网络利用率。你在用磁盘吗?你确定你的外部服务没有用完吗?它们可能有并发限制。
我想你已经提高了.NET连接限制?!找出实际同时发出的请求数。我会这样做:
- 暂停调试器并确保当前.NET web堆栈中有许多线程
- 查看打开的TCP连接数(Process Explorer或TcpView.exe)
- 使用Fiddler并查看有多少请求似乎同时处于活动状态