我有一块代码检查http/s端点的状态和加载时间。然后,对于每个顶级页面,请检查级别1 HREFS,以检查页面引用的所有内容是否也加载了200个。
(我检查50个顶级页面,每个顶级页面平均具有8个链接)
我通过一些goroutines(25)和一个候补组检查顶级页面。对于1级页面,我尝试了另一个Gouroutines WaitGroup,然后是一个直线(只是为了比较)。
在这些级别1页面上,我得到了很多"客户端"错误。当我抓住这样的URL并立即用卷曲重试时,它可以完美加载(用卷发)
标题上的超时是JS,PNG,GIF,HTML的混合物。当我手动卷曲时,普通的东西可以很好地工作,但是以某种方式失败了。
以下是我调用以获取页面内容的功能。
func (t Target) getContents(timeout int64) (string, string, string) {
var contents []byte
statusCode := "0"
errorLabel := "no_error"
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
// Dial: (&net.Dialer{
// Timeout: 15 * time.Second,
// KeepAlive: 15 * time.Second,
// }).Dial,
TLSHandshakeTimeout: 10 * time.Second,
ResponseHeaderTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
client := &http.Client{Transport: tr, Timeout: time.Duration(timeout) * time.Second}
url := t.getPageURL()
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Error("Error while creating the request| ", err)
errorLabel = "cant_create_request"
} else {
//req.Header.Add("cache-control", "no-cache")
if t.Agent != "" {
req.Header.Set("User-Agent", t.Agent)
}
if t.SourceIP != "" {
req.Header.Set("X-Forwarded-For", t.SourceIP)
}
if t.Host != "" {
req.Header.Set("Host", t.Host)
req.Host = t.Host
}
response, err := client.Do(req)
if err != nil {
log.Error("Error while doing the request| ", err.Error())
errorLabel = "cant_do_request"
} else {
defer response.Body.Close()
statusCode = strconv.Itoa(response.StatusCode)
contents, err = ioutil.ReadAll(response.Body)
if err != nil {
log.Error("Error while reading the response| ", err)
errorLabel = "cant_read_response"
}
}
}
return string(contents), statusCode, errorLabel
}
这应该是评论,而不是答案,但我没有足够的观点来评论:(
也许您应该尝试不根据每个请求定义TR和客户端。
如果您同时启动了许多并行请求,则根据目标服务器和客户端系统的不同,可能会出现问题。这可以解释为什么单个测试请求之后可以。
最后,我根本不是专家,但我认为您应该避免使用nil:
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Error("Error while creating the request| ", err)
errorLabel = "cant_create_request"
} else {
...
}
return string(contents), statusCode, errorLabel
不应该是:
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Error("Error while creating the request| ", err)
return string(contents), statusCode, "cant_create_request" //return nil instead ?
}
...
return string(contents), statusCode, errorLabel
很难读取和错误易于读取。