pym*_*ymd 91 timeout get http go
我在Go中创建一个URL提取器,并有一个要获取的URL列表.我向http.Get()
每个URL 发送请求并获取其响应.
resp,fetch_err := http.Get(url)
Run Code Online (Sandbox Code Playgroud)
如何为每个Get请求设置自定义超时?(默认时间很长,这使得我的提取器非常慢.)我希望我的提取器有超过40-45秒的超时时间,之后它应该返回"请求超时"并继续下一个URL.
我怎样才能做到这一点?
spa*_*ovv 236
显然在Go 1.3中,http.Client有Timeout字段
client := http.Client{
Timeout: 5 * time.Second,
}
client.Get(url)
Run Code Online (Sandbox Code Playgroud)
这对我来说已经成功了.
Vol*_*ker 52
您需要使用自己的传输设置自己的客户端,该传输使用自定义拨号功能,该功能包裹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")
}
Run Code Online (Sandbox Code Playgroud)
dmi*_*ael 30
要添加到Volker的答案,如果除了连接超时之外还要设置读/写超时,您可以执行以下操作
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),
},
}
}
Run Code Online (Sandbox Code Playgroud)
此代码已经过测试并正在生产中.有关测试的完整要点,请访问 https://gist.github.com/dmichael/5710968
请注意,您需要为每个请求创建一个新客户端,因为conn.SetDeadline
它将来引用一个点time.Now()
zan*_*ngw 24
Go 模块中有几个客户端超时http
,并且当前答案中有一些这些超时的示例。
这是一张图片来说明客户端超时,请参阅Go net/http 超时的完整指南
有两种方法可以设置HTTP请求的超时时间
client := http.Client{
Timeout: 3 * time.Second,
}
resp, err := client.Do(req)
Run Code Online (Sandbox Code Playgroud)
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, URL)
Run Code Online (Sandbox Code Playgroud)
- 使用上下文是特定于请求的,而使用客户端超时可能会应用于传递给
Do
客户端方法的所有请求。- 如果您想专门
deadline/timeout
处理每个请求,则使用上下文,否则,如果您希望每个出站请求有 1 个超时,则使用客户端超时就足够了。
Cha*_*ant 11
如果您希望按请求执行此操作,则会因为简洁而忽略错误处理:
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))
Run Code Online (Sandbox Code Playgroud)
快速而肮脏的方式:
http.DefaultTransport.(*http.Transport).ResponseHeaderTimeout = time.Second * 45
Run Code Online (Sandbox Code Playgroud)
这是在没有任何协调的情况下改变全球状态.但是你的网址提取器可能还可以.否则创建一个私有实例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)
...
Run Code Online (Sandbox Code Playgroud)
以上没有测试过.
归档时间: |
|
查看次数: |
80739 次 |
最近记录: |