Как установить тайм-аут для http.Получить () запросы в Golang?
Я делаю url fetcher в Go и есть список URL-адресов для извлечения. Я посылаю http.Get()
запросы к каждому URL и получить их ответ.
resp,fetch_err := http.Get(url)
Как я могу установить пользовательский тайм-аут для каждого запроса GET? (Время по умолчанию очень долго, и это делает мой fetcher очень медленным.) Я хочу, чтобы мой fetcher имел тайм-аут около 40-45 секунд, после чего он должен вернуть "время ожидания запроса" и перейти к следующему URL.
Как я могу этого достичь?
6 ответов:
видимо в Go 1.3 http.Клиент имеет поле тайм-аута
timeout := time.Duration(5 * time.Second) client := http.Client{ Timeout: timeout, } client.Get(url)
что сделал трюк для меня.
вам нужно настроить свой собственный клиент своими транспорт который использует a пользовательская функция набора, которая обертывает DialTimeout.
что-то вроде (полностью непроверенные)этой:
var timeout = time.Duration(2 * time.Second) func dialTimeout(network, addr string) (net.Conn, error) { return net.DialTimeout(network, addr, timeout) } func main() { transport := http.Transport{ Dial: dialTimeout, } client := http.Client{ Transport: &transport, } resp, err := client.Get("http://some.url") }
чтобы добавить к ответу Волкера, если вы также хотите установить тайм-аут чтения/записи в дополнение к тайм-ауту подключения, вы можете сделать что-то вроде следующего
package httpclient import ( "net" "net/http" "time" ) func TimeoutDialer(cTimeout time.Duration, rwTimeout time.Duration) func(net, addr string) (c net.Conn, err error) { return func(netw, addr string) (net.Conn, error) { conn, err := net.DialTimeout(netw, addr, cTimeout) if err != nil { return nil, err } conn.SetDeadline(time.Now().Add(rwTimeout)) return conn, nil } } func NewTimeoutClient(connectTimeout time.Duration, readWriteTimeout time.Duration) *http.Client { return &http.Client{ Transport: &http.Transport{ Dial: TimeoutDialer(connectTimeout, readWriteTimeout), }, } }
этот код протестирован и работает в производстве. Полная суть с тестами доступна здесь https://gist.github.com/dmichael/5710968
имейте в виду, что вам нужно будет создать новый клиент для каждого запроса из-за
conn.SetDeadline
, который ссылается на точку в будущем отtime.Now()
быстрый и грязный способ:
http.DefaultTransport.(*http.Transport).ResponseHeaderTimeout = time.Second * 45
это мутация глобального состояния без какой-либо координации. Тем не менее, это может быть возможно хорошо для вашего url fetcher. В противном случае создайте частный экземпляр
http.RoundTripper
:var myTransport http.RoundTripper = &http.Transport{ Proxy: http.ProxyFromEnvironment, ResponseHeaderTimeout: time.Second * 45, } var myClient = &http.Client{Transport: myTransport} resp, err := myClient.Get(url) ...
ничего выше не было проверено.
вы можете использовать https://github.com/franela/goreq который обрабатывает тайм-ауты в моде и простым способом.