golang 海量URL访问,如何提升性能

我有100M的URL,需要访问这些URL,看看哪些能访问。
从CSV中读取URL,如果能访问就存入另一个CSV。
目前,我将100M的文件拆分成了20个,逐个访问。每次全部读入管道,然后由消费者去处理(测试访问能否成功),处理完的数据再存入管道,主程序从管道中读数据,写入文件,如果监测到没数据了,就结束。
目前100万个URL 大约需要2小时。(现在有1亿个)
请问如何才能更高效的处理。

package main

import (
    "encoding/csv"
    "fmt"
    "net/http"
    "os"
    "time"
)

func fileWrite(filename string, content string) {
    f, error := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0660)
    if error != nil {
        fmt.Println(error.Error())
    }
    defer f.Close()
    f.WriteString(content)
}

func consumer(channel_in chan string, channel_out chan string) {

    for domain := range channel_in {

        url := "http://" + domain
        client := http.Client{
            Timeout: 1 * time.Second,
        }
        res, error := client.Get(url)
        if error == nil && res.StatusCode == http.StatusOK {
            channel_out <- domain + "\n"
        }
    }

}

const READ_PATH = "./split/16.csv"
const WRITE_PATH = "./canVisit/16.csv"

func main() {
    //读文件
    file, _ := os.Open(READ_PATH)
    defer file.Close()
    reader := csv.NewReader(file)
    content, _ := reader.ReadAll()
    contentLen := len(content)

    //用来存整个CSV文件的数据
    productChannel := make(chan string, contentLen)
    //消费者会将处理好的数据放入writeChannel
    writeChannel := make(chan string, contentLen)

    defer close(productChannel)

    //将文件内容全部放入管道
    for _, row := range content {
        productChannel <- row[0]
    }

    //消费者处理管道中的数据
    for i := 0; i < 100; i++ {
        go consumer(productChannel, writeChannel)
    }
    for {
        select {
        case item := <-writeChannel:
            fileWrite(WRITE_PATH, item)
        case <-time.After(time.Second * 10):
            goto out
        }
    }
out:
    fmt.Println("over!")
}
阅读 2.1k
1 个回答

提个想法,可以换head请求,减少Get接收响应体的时间

另外就是可以根据域名批量排除,比如访问一个域名出现dns错误或者ssl错误、不能建立连接,就假定整个域名下都不能访问

还有超时也可以再压短一些

这样会不够准确,所以可以再开个慢速的测试线程,把第一次测试认为是有问题的url再试一次,放宽超时再允许重试

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题