在GO中跟踪HTTP请求时指定超时



我知道通过以下方式指定使用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。所有goroutines射击,但最终该程序以30秒以上的结尾,好像超时为30秒。

之前,我通过使用骇人听闻的方式将其内部默认值更改为10秒,并且任何花费太长时间的方法,时间到了,该程序以10.xxx秒结束,但现在它的时间为30.xx,我也做了同样的工作。秒

在这种情况下指定超时的正确方法是什么?

我知道通过执行以下方式指定使用HTTP请求的超时的方法。

httpClient := http.Client{
    Timeout: time.Duration(5 * time.Second),
}

实际上,首选方法是在请求上使用context.context。您使用的方法只是一个适合简单用例的缩短切割。

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)

此方法也适用于您的情况。

最新更新