前段时间我尝试在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图表......),然后来到这里,但我跑了出于答案。我想知道这种行为是否可以解释。我意识到这个问题中有很多“ifs”,但如果没有它变成一篇文章,它就是我能做的最好的。
我的电脑规格是i5 4460,配备8GB DDR3-1600和100Mb / s(实际上大约8MB / s)的互联网连接,通过LAN直接连接到爬虫。我正在寻找一般方向 - 我应该在哪里看看 (我的意思是对于经验丰富的开发人员而不是我自己而言清晰的东西),以便:
我已经考虑过路由器本身(Netgear N600)限制传出连接的数量(看起来很奇怪),所以我使连接数量饱和,而不是带宽,但是无法弄清楚这是否均匀可能的。
任何一般方向/建议都会受到热烈欢迎:)随意指出新的错误,这就是我的学习方法。
阿米尔。
答案 0 :(得分:0)
问题不在于DNS解析,因为创建与IP地址的连接(我预先存储了所有地址然后使用了这些地址)导致完全相同的响应时间和带宽使用。也不是线程问题。
我怀疑现在是netlimiter程序的“错误”。我直接测量了接收到的字节数并将它们输出到磁盘上(我以前做过这个,但显然我在程序中做了一些改动)。看来我真的让带宽饱和了。此外,当切换到HttpUrlConnection对象而不是Jsoup时,netlimiter程序确实显示了更大的带宽使用。也许它与Jsoup存在一些问题。 我不确定这是不是问题,但根据经验,该程序会下载很多的数据。所以我希望这有助于将来可能遇到类似问题的任何人。