Cómo establecer el tiempo de espera para http.Get () solicitudes en Golang?
Estoy haciendo una búsqueda de URL en Go y tengo una lista de URL para obtener. Envío http.Get()
solicitudes a cada URL y obtengo su respuesta.
resp,fetch_err := http.Get(url)
¿Cómo puedo establecer un tiempo de espera personalizado para cada solicitud Get? (El tiempo predeterminado es muy largo y eso hace que mi recuperador sea muy lento.) Quiero que mi recuperador tenga un tiempo de espera de alrededor de 40-45 segundos después de lo cual debería devolver "request timed out" y pasar a la siguiente URL.
¿Cómo puedo lograr esto?
6 answers
Aparentemente en Go 1.3 http.Cliente tiene campo de tiempo de espera
timeout := time.Duration(5 * time.Second)
client := http.Client{
Timeout: timeout,
}
client.Get(url)
Eso ha hecho el truco para mí.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-03 12:12:42
Necesita configurar su propio Cliente con su propio Transporte que utiliza un función de marcación personalizada que envuelve DialTimeout .
Algo así como (completamente no probado) esto:
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")
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-03 11:40:24
Para agregar a la respuesta de Volker, si también desea establecer el tiempo de espera de lectura/escritura además del tiempo de espera de conexión, puede hacer algo como lo siguiente
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),
},
}
}
Este código se prueba y está funcionando en producción. El resumen completo con las pruebas está disponible aquí https://gist.github.com/dmichael/5710968
Tenga en cuenta que tendrá que crear un nuevo cliente para cada solicitud debido a la conn.SetDeadline
que hace referencia a un punto en el futuro de time.Now()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-03 12:13:19
Un camino rápido y sucio:
http.DefaultTransport.(*http.Transport).ResponseHeaderTimeout = time.Second * 45
Esto es estado global mutante sin ninguna coordinación. Sin embargo, es posible que esté bien para su url fetcher. De lo contrario, cree una instancia privada de 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)
...
Nada de lo anterior fue probado.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-03 11:36:04
Puede usar https://github.com/franela/goreq que maneja los tiempos de espera de una manera sencilla.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-21 19:42:44
Si desea hacerlo por solicitud, err manejo ignorado por brevedad:
ctx, cncl := context.WithTimeout(context.Background(), time.Second*3)
defer cncl()
req, _ := http.NewRequest(http.MethodGet, "https://google.com", nil)
resp, _ := http.DefaultClient.Do(req.WithContext(ctx))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-27 21:41:47