如何为每个获取请求设置自定义超时? (默认时间很长,这使我的fetcher真的很慢。)我希望我的fetcher超时约为40-45秒,然后它应该返回“请求时间”,然后转到下一个URL。
我怎么能实现?在GO 1.3
Http.client
具有超时字段
client := http.Client{
Timeout: 5 * time.Second,
}
client.Get(url)
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")
}
如果您想根据请求执行此操作,则为简洁而忽略了错误处理:
ctx, cncl := context.WithTimeout(context.Background(), time.Second*3)
defer cncl()
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "https://google.com", nil)
resp, _ := http.DefaultClient.Do(req)
要添加沃尔克的答案,如果您还想设置读/写入超时,除了连接超时,您还可以执行以下操作。
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
意识到,您需要为每个请求创建一个新客户
在GO
Context它们之间的差异是使用client client超时可以应用于所有请求
通过到
client := http.Client{
Timeout: 3 * time.Second,
}
resp, err := client.Do(req)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, URL)
Do
这种与任何协调都在变异的全球状态。但是对于您的URL Fetcher来说可能还可以。否则创建一个私有实例::
deadline/timeout
上面没有测试。
http.DefaultTransport.(*http.Transport).ResponseHeaderTimeout = time.Second * 45
这可能会有所帮助,但请注意,仅在建立连接后才开始。