在Go中发送多个请求时发生零星的EOF错误
问题描述:
让我首先说我是Go的新手,并欢迎任何指示/更正。在Go中发送多个请求时发生零星的EOF错误
我想写一个小的Go应用程序,它将创建一些DNS查询并将它们发送到各自的Go例程中。我从一个包含1000个URL的文件中获取URL并创建一个切片,对切片中的每个URL我为A记录进行查询,并在成功时将URL和经过的时间推送到结果通道,并且如果出现错误各自的错误通道。然后,我听取选择。
我一直在努力的是,当使用TCP时,我会收到(看似随机)的一些EOF错误,并在使用UDP时收到I/O超时错误。我想使用TCP并确保响应,我失去了为什么我会得到一个EOF错误。这也发生,如果我做1000次查询到同一URL VS 1000个不同的网址
上OSX和围棋版本工作1.6
这是我到目前为止有:
package main
import (
"bufio"
"fmt"
"github.com/miekg/dns"
"os"
"time"
)
// CHECK AND PRINT ERRORS
func checkErr(e error) {
if e != nil {
fmt.Println("Error: %s", e)
}
}
// MAKES A SLICE OF URLS FROM TXT FILE
func urlSlice() []string {
result := []string{}
file, err := os.Open("topsites.txt")
checkErr(err)
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
result = append(result, scanner.Text())
}
return result
}
func makeQuery(target string) (string, error) {
server := "8.8.8.8"
// WILL RECIEVE EOF ERROR IF TCP - I/O TIMEOUT IF UDP
c := dns.Client{Net: "tcp", Timeout: time.Duration(100 * time.Second)}
m := dns.Msg{}
m.SetQuestion(dns.Fqdn(target+"."), dns.TypeA)
_, t, err := c.Exchange(&m, server+":53")
if err != nil {
return "", err
}
return "Url: " + target + " - - Took: " + t.String(), nil
}
func main() {
start := time.Now()
targets := urlSlice()
resch, errch := make(chan string), make(chan error)
for _, url := range targets {
go func(url string) {
res, err := makeQuery(url)
if err != nil {
errch <- err
return
}
resch <- res
}(url)
}
for i := 0; i < len(targets); i++ {
select {
case res := <-resch:
fmt.Println(res)
case err := <-errch:
fmt.Println(err)
}
}
elapsed := time.Since(start)
fmt.Println("\ntotal time elapsed: ", elapsed)
}
输出:
Url: facebook.com - - Took: 548.582107ms
Url: wordpress.com - - Took: 548.805505ms
Url: google.com.br - - Took: 541.491363ms
Url: onclickads.net - - Took: 548.16544ms
Url: bongacams.com - - Took: 543.28688ms
Url: tianya.cn - - Took: 543.41525ms
Url: blogger.com - - Took: 544.461005ms
Url: alibaba.com - - Took: 543.53541ms
Url: gmw.cn - - Took: 543.56093ms
Url: pornhub.com - - Took: 664.297282ms
Url: outbrain.com - - Took: 664.423217ms
Url: ask.com - - Took: 671.557037ms
EOF
EOF
EOF
EOF
EOF
EOF
EOF
Url: t.co - - Took: 1.166130918s
Url: youth.cn - - Took: 1.946658912s
Url: apple.com - - Took: 2.763568935s
...continued...
total time elapsed: 23.703546858s
想法,建议和帮助所有赞赏。谢谢!
答
这可能会感兴趣:https://idea.popcount.org/2013-11-28-how-to-resolve-a-million-domains/
根据这篇文章,天真的方法是通过多少UDP套接字可以同时打开限制 - 1000左右我将承担同样是真正的TCP套接字 - 您将耗尽文件描述符或其他资源。
笔者在文章的末尾提供了一个链接到他的平行DNS解析:https://github.com/majek/goplayground/blob/master/resolve/resolve.go
他使用去例程在同一UDP端口的所有通信的配置数量。我猜如果你想使用TCP,你将不得不使用TCP连接每个去程序(与例程数远低于1000)
我的第一个想法是你超载的东西,也许速率限制为X并发请求会有所帮助? – Plato
我以为同样的事情,似乎〜200查询将导致没有错误,但是,我仍然不确定为什么EOF和如何解决它。我希望能够生成请求,将它们推出,并等待响应。 –