不会武功的令狐冲 2021-12-22 10:38 采纳率: 0%
浏览 26

Golang 海量URL高并发怎么优雅实现

问题遇到的现象和发生背景

简单化版的需求:100M的URL存在CSV文件中,需要读文件,然后逐个访问URL,如果状态码为200就存到CSV文件中。

问题相关代码,请勿粘贴截图
package main
import (
    "encoding/csv"
    "fmt"
    "net/http"
    "os"
    "sync"
    "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!")
}


运行结果及报错内容
我的解答思路和尝试过的方法

这种方式大概100万URL 需要1.9个小时才能访问完。 但我大概有1个亿的URL。

我想要达到的结果

希望大家能帮帮忙,提一提建议。能力强的话,可以手撕一份代码

  • 写回答

1条回答 默认 最新

  • CSDN专家-黄老师 2021-12-22 11:36
    关注

    你这个是并发了100,但你每一个并发都是从通道channel_in 获取url,将所有url改为切片,每个并发截取不同的切片进行处理,如果100个并发都从一个通道channel_in 获取url,这个可能会有资源争夺延时的可能

    评论

报告相同问题?

问题事件

  • 修改了问题 12月22日
  • 创建了问题 12月22日

悬赏问题

  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能
  • ¥15 jmeter脚本回放有的是对的有的是错的
  • ¥15 r语言蛋白组学相关问题