问题描述
我知道通过以下方法指定HTTP请求超时的常用方法:
I know the usual method of specifying a timeout with HTTP requests by doing:
httpClient := http.Client{
Timeout: time.Duration(5 * time.Second),
}
但是,我似乎无法弄清楚在跟踪HTTP请求时该如何做.这是我正在使用的代码段:
However, I can't seem to figure out how to do the same when tracing HTTP requests. Here is the piece of code I am working with:
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个网址.所有goroutine都会触发,但最终程序会在30秒以上结束,就好像超时为30秒一样.
I am firing this function inside a goroutine. My sample data set is 100 urls. All goroutines fire, but eventually the program ends in 30+ secs as if the timeout is 30secs.
之前,我通过使用hacky方法将其内部默认值更改为10秒,并且花了太长时间,超时并且该程序以10.xxx秒结束,但现在花费了30.xx,这一切都可以正常工作秒.
Earlier I made the same to work by using the hacky way of changing the default inside of it to 10 secs and anything that took too long, timed out and the program ended at 10.xxx secs but now its taking 30.xx secs.
在这种情况下,指定超时的正确方法是什么?
What would be a proper way of specifying a timeout in this scenario?
推荐答案
httpClient := http.Client{
Timeout: time.Duration(5 * time.Second),
}
实际上,首选方法是在请求上使用 context.Context .您使用的方法只是适合简单用例的捷径.
Actually, the preferred method is to use a context.Context on the request. The method you've used is just a short-cut suitable for simple use cases.
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
ctx, cancel := context.WithTimeout(context.Background(), 5 * time.Second)
defer cancel()
req = req.WithContext(ctx)
此方法也应适合您的情况.
And this method should work nicely for your situation as well.
这篇关于在Go中跟踪HTTP请求时指定超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!