【问题标题】:Many Java threads downloading content from web - but not saturating the bandwidth许多 Java 线程从 Web 下载内容 - 但没有使带宽饱和
【发布时间】:2023-04-05 16:10:01
【问题描述】:

不久前,我尝试在 Java 中实现一个爬虫并离开该项目一段时间(此后取得了很大进展)。基本上我已经实现了一个具有大约 200-400 个线程的爬虫,每个线程连接并下载一页的内容(为清楚起见进行了简化,但基本上就是这样):

// we're in a run() method of a truely generic Runnable.
// _url is a member passed to the Runnable object beforehand.

Connection c = Jsoup.connect(_url).timeout(10000);

c.execute();

Document d = c.response().parse();

// use Jsoup to get the links, add them to the backbone of the crawler
// to be checked and maybe later passed to the crawling queue.

这行得通。问题是我只使用了我互联网带宽的一小部分。由于能够以 >6MB/s 的速度下载,我发现(使用 NetLimiter 和我自己的计算)我在下载页面源时充其量仅使用大约 1MB/s。

我做了很多统计和分析,这在某种程度上是合理的 - 如果计算机无法有效地支持超过 400 个线程(我也不知道,但数量更大线程似乎无效)并且每个连接大约需要 4 秒才能完成,然后我应该每秒下载 100 页,这确实是发生了什么。奇怪的是,当我运行这个程序时,互联网连接完全阻塞 - 我和我的 wifi 连接上的其他任何人都无法正常访问网络(当我只使用 16% 时) ! 在下载其他文件(例如电影)时不会发生)。

在来这里之前,我已经花了数周时间计算、分析和收集各种统计数据(确保所有线程都在使用 VM 监视器运行,计算线程的平均运行时间,excel 图表......),但我已经跑了没有答案。我想知道这种行为是否可以解释。我知道这个问题有很多“如果”,但这是我能做的最好的事情,而不把它变成一篇文章。

我的电脑规格是 i5 4460,配备 8GB DDR3-1600 和 100Mb/s(实际上约为 8MB/s)互联网连接,通过 LAN 直接连接到爬虫。我正在寻找大体方向 - 我还应该去哪里寻找 (我的意思是有经验的开发人员清楚的明显的东西,而不是我自己),以便:

  1. 提高下载速度(可能不是 Jsoup?线程数不同?我已经尝试使用选择器代替线程,但速度较慢),或者:
  2. 在我运行此程序时释放互联网。

我考虑过路由器本身(Netgear N600)限制传出连接的数量(似乎很奇怪),所以我正在饱和连接数量,而不是带宽,但无法弄清楚这是否是偶数可能。

任何大方向/建议都会受到热烈欢迎 :) 随时指出新的错误,这就是我学习的方式。

阿米尔。

【问题讨论】:

  • 我可能会有一个单独的线程池用于下载和另一个用于解析。解析受 CPU 限制,因此解析器线程数多于内核可能会减慢速度,而您可能希望下载池动态调整大小,该池通常比解析器池大得多。这不一定能解决您的问题,但会使调优变得容易得多。
  • 我会把它归咎于路由器,也可能归咎于您的提供商。这种程序在(虚拟)服务器主机上的服务器上运行得更好。与居民相比,托管者与互联网的连接(更快、相同)不同。
  • 另外,如果您正在下载许多小页面,那么 HTTP 偷听可能会导致您的实际带宽使用量增加一倍或三倍。
  • @PeterMmm 也有可能当您的连接数饱和时,您无法再进行 DNS 查找,或者至少我在一些路由器上也看到过这种情况。
  • 嗯,400 个线程确实不是最好的主意。现代方法是使用Java NIO 进行输入多路复用。这是tutorial for newbies

标签: java multithreading web-crawler jsoup router


【解决方案1】:

问题不在于 DNS 解析,因为使用 IP 地址创建连接(我预先存储了所有地址,然后使用了这些地址)导致完全相同的响应时间和带宽使用。也不是线程问题。

我现在怀疑是 netlimiter 程序的“错误”。我已经直接测量了接收到的字节数并将其输出到磁盘(我以前做过,但显然我在程序中做了一些更改)。看来我真的使带宽饱和了。此外,当切换到 HttpUrlConnection 对象而不是 Jsoup 时,netlimiter 程序确实显示出更大的带宽使用量。也许它与 Jsoup 有一些问题。 我不确定这是否是问题所在,但根据经验,该程序会下载 大量 数据。所以我希望这对以后可能遇到类似问题的人有所帮助。

【讨论】:

    猜你喜欢
    • 2013-12-15
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    相关资源
    最近更新 更多