首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >没有外部依赖的高性能网络蜘蛛

没有外部依赖的高性能网络蜘蛛
EN

Stack Overflow用户
提问于 2015-12-18 00:16:41
回答 1查看 92关注 0票数 2

我正在尝试用Golang编写我的第一个网络蜘蛛。它的任务是从提供的数据库查询中爬取域(并检查它们的html)。我们的想法是没有第三方依赖(例如消息队列),或者尽可能少,但它必须有足够的性能来抓取每天500万个域名。我有大约1.5亿个域名,我需要检查每个月。

下面最基本的版本-它运行在“无限循环”中,因为理论上爬行过程将是无穷无尽的。

代码语言:javascript
复制
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核心的服务器。

EN

回答 1

Stack Overflow用户

发布于 2015-12-18 01:19:28

为什么会有计时组件呢?

只需创建一个向其提供URL的通道,然后生成N个goroutines,在该通道上循环并执行此工作。

然后只需调整N的值,直到CPU/内存的利用率达到90%左右(以适应站点响应时间的波动)

类似于以下内容(on Play):

代码语言:javascript
复制
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")
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34339353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档