问题遇到的现象和发生背景
简单化版的需求: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。
我想要达到的结果
希望大家能帮帮忙,提一提建议。能力强的话,可以手撕一份代码