最近需要查一个用户登录失败的问题,怀疑是DNS有问题。网上找了一些公开的DNS服务器检测了一下,公开的服务器列表在 http://public-dns.info
刚开始使用python同步跑,那个慢啊,想用gevent跑又没有搜到dnspython配合gevent的栗子。
最后找了个go的改了改竟然跑通了,我加上了channel控制并发,速度快还稳定,go好帅!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

package main

import (
"fmt"
"time"
"log"
"bufio"
"os"
"strings"
"github.com/miekg/dns"
)

var (
maxRoutineNum = 10
)


func lookup(domain string, server string, channel chan string, total chan int) {
c := dns.Client{}
m := dns.Msg{}
m.SetQuestion(domain +".", dns.TypeA)
r, t, err := c.Exchange(&m, server+":53")
<- total
if r == nil {
seconds := 0
fail_time := time.Duration(seconds)*time.Second
channel <- server + " " + fail_time.String()
} else {
if err != nil {
//log.Fatal(err)
seconds := 0
fail_time := time.Duration(seconds)*time.Second
channel <- server + " " + fail_time.String()
} else {
channel <- server + " " + t.String()
}
}
/*
for _, ans := range r.Answer {
//Arecord := ans.(*dns.CNAME)
//Arecord := ans.(*dns.CNAME)
fmt.Println(ans)
}
*/

}

func main() {
domain := "solos.so"
total := make(chan int, maxRoutineNum)
channel := make(chan string)
lines := 0

if file, err := os.Open("nameservers.csv"); err == nil {

defer file.Close()

scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
s := strings.Split(line, ",")
server := s[0]
if strings.Contains(server, ":") {
continue
}
total <- -1
lines += 1
go lookup(domain, server, channel, total)
}

if err = scanner.Err(); err != nil {
log.Fatal(err)
}

} else {
log.Fatal(err)
}

resultFile := "result.txt"
fout, err := os.Create(resultFile)
defer fout.Close()
if err != nil {
fmt.Println(resultFile,err)
return
}

i := 0
for i < lines {
i += 1
resp := <- channel
fout.WriteString(resp)
fout.WriteString("\n")
}
}

参考:
Why golang Lookup* function can’t provide a server parameter