我知道通过执行以下操作来指定 HTTP 请求超时的常用方法:
httpClient := http.Client{
Timeout: time.Duration(5 * time.Second),
}
但是,我似乎不知道在跟踪 HTTP 请求时如何执行相同的操作。这是我正在使用的代码片段:
func timeGet(url string) (httpTimingBreakDown, error) {
req, _ := http.NewRequest("GET", url, nil)
var start, connect, dns, tlsHandshake time.Time
var timingData httpTimingBreakDown
timingData.url = url
trace := &httptrace.ClientTrace{
TLSHandshakeStart: func() { tlsHandshake = time.Now() },
TLSHandshakeDone: func(cs tls.ConnectionState, err error) { timingData.tls = time.Since(tlsHandshake) },
}
req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
start = time.Now()
http.DefaultTransport.(*http.Transport).ResponseHeaderTimeout = time.Second * 10 // hacky way, worked earlier but don't work anymore
if _, err := http.DefaultTransport.RoundTrip(req); err != nil {
fmt.Println(err)
return timingData, err
}
timingData.total = time.Since(start)
return timingData, nil
}
我在 goroutine 中触发这个函数。我的示例数据集是 100 个 url。所有 goroutine 都会触发,但最终程序会在 30 秒以上结束,就好像超时是 30 秒一样。
早些时候,我通过使用 hacky 方法将其内部默认值更改为 10 秒,以及任何花费太长时间、超时且程序在 10.xxx 秒结束但现在需要 30.xx 秒的方法来实现相同的工作。
在这种情况下指定超时的正确方法是什么?