我正在尝试用Golang编写我的第一个网络蜘蛛。它的任务是从提供的数据库查询中爬取域(并检查它们的html)。我们的想法是没有第三方依赖(例如消息队列),或者尽可能少,但它必须有足够的性能来抓取每天500万个域名。我有大约1.5亿个域名,我需要检查每个月。
下面最基本的版本-它运行在“无限循环”中,因为理论上爬行过程将是无穷无尽的。
func crawl(n time.Duration) {
var wg sync.WaitGroup
runtime.GOMAXPROCS(runtime.NumCPU())
for _ = range time.Tick(n * time.Second) {
wg.Add(1)
go func() {
defer wg.Done()
// do the expensive work here - query db, crawl domain, inspect html
}()
}
wg.Wait()
}
func main() {
go crawl(1)
select{}
}目前在4个CPU核心上运行这段代码意味着它可以在24小时((60 * 60 * 24) * 4)内以给定的阈值1s执行最多345600个请求。至少这是我的理解:-)如果我的想法是正确的,那么我就需要想出比以前快14倍的解决方案来满足日常需求。
我将感谢您的建议,使爬虫更快,但没有解决复杂的堆栈设置或购买更多的CPU核心的服务器。
发布于 2015-12-18 01:19:28
为什么会有计时组件呢?
只需创建一个向其提供URL的通道,然后生成N个goroutines,在该通道上循环并执行此工作。
然后只需调整N的值,直到CPU/内存的利用率达到90%左右(以适应站点响应时间的波动)
类似于以下内容(on Play):
package main
import "fmt"
import "sync"
var numWorkers = 10
func crawler(urls chan string, wg *sync.WaitGroup) {
defer wg.Done()
for u := range urls {
fmt.Println(u)
}
}
func main() {
ch := make(chan string)
var wg sync.WaitGroup
for i := 0; i < numWorkers; i++ {
wg.Add(1)
go crawler(ch, &wg)
}
ch <- "http://ibm.com"
ch <- "http://google.com"
close(ch)
wg.Wait()
fmt.Println("All Done")
}https://stackoverflow.com/questions/34339353
复制相似问题