Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
许多Java线程从web下载内容,但不会使带宽饱和_Java_Multithreading_Web Crawler_Jsoup_Router - Fatal编程技术网

许多Java线程从web下载内容,但不会使带宽饱和

许多Java线程从web下载内容,但不会使带宽饱和,java,multithreading,web-crawler,jsoup,router,Java,Multithreading,Web Crawler,Jsoup,Router,不久前,我尝试用Java实现一个爬虫程序,并离开了该项目一段时间(此后取得了很大进展)。基本上,我已经实现了一个大约200-400个线程的爬虫程序,每个线程连接并下载一个页面的内容(为了清晰起见,进行了简化,但基本上就是这样): 这很有效。问题是我只使用了互联网带宽的一小部分。由于能够以>6MB/s的速度下载,我已经确定(使用NetLimitor和我自己的计算)在下载页面源时最多只能使用大约1MB/s 我已经做了大量的统计和分析,这是合理的-如果计算机不能有效地支持超过400个线程(我也不知道,

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

这很有效。问题是我只使用了互联网带宽的一小部分。由于能够以>6MB/s的速度下载,我已经确定(使用NetLimitor和我自己的计算)在下载页面源时最多只能使用大约1MB/s

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

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

我的电脑规格为i5 4460,配备8GB DDR3-1600和100Mb/s(有效约8MB/s)互联网连接,通过局域网直接连接到爬虫。我在寻找大致的方向——我还应该去哪里 (我指的是对有经验的开发人员而不是我自己清楚的令人讨厌的东西)为了:

  • 提高下载速度(可能不是Jsoup?线程数不同?我已经尝试使用选择器而不是线程,但速度较慢),或者:
  • 当我运行此程序时,请释放internet
  • 我曾经考虑过路由器本身(Netgear N600)限制传出连接的数量(看起来很奇怪),因此我正在饱和连接的数量,而不是带宽,但无法确定这是否可能

    任何一般性的指导/建议都将受到热烈欢迎:)请随意指出新的错误,这就是我学习的方式


    Amir.

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

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

    我可能会有一个单独的线程池用于下载,另一个用于解析。解析是受CPU限制的,因此拥有比内核更多的解析器线程可能会降低速度,而您可能希望动态调整下载池的大小,下载池通常比解析器池大得多。这不一定能解决你的问题,但它使调整变得容易得多。我会把责任推到路由器上,可能也推到你的提供商身上。这种程序在(虚拟)服务器宿主的服务器上运行得更好。主机与Internet的连接不同(更快、更简单)。此外,如果您正在下载许多小页面,那么HTTP窃听器可能会使您的实际带宽使用量增加一倍或三倍。@petermm也有可能当连接数达到饱和时,您无法再进行DNS查找,或者至少我在一些路由器上也看到了这一点。嗯,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.