文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
问题
来看一段日常代码。
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"time"
)
var tr *http.Transport
func init() {
tr = &http.Transport{
MaxIdleConns: 100,
Dial: func(netw, addr string) (net.Conn, error) {
conn, err := net.DialTimeout(netw, addr, time.Second*2) //设置建立连接超时
if err != nil {
return nil, err
}
err = conn.SetDeadline(time.Now().Add(time.Second * 3)) //设置发送接受数据超时
if err != nil {
return nil, err
}
return conn, nil
},
}
}
func main() {
for {
_, err := Get("http://www.baidu.com/")
if err != nil {
fmt.Println(err)
break
}
}
}
func Get(url string) ([]byte, error) {
m := make(map[string]interface{})
data, err := json.Marshal(m)
if err != nil {
return nil, err
}
body := bytes.NewReader(data)
req, _ := http.NewRequest("Get", url, body)
req.Header.Add("content-type", "application/json")
client := &http.Client{
Transport: tr,
}
res, err := client.Do(req)
if res != nil {
defer res.Body.Close()
}
if err != nil {
return nil, err
}
resBody, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
return resBody, nil
}
做的事情,比较简单,就是循环去请求 http://www.baidu.com/ , 然后等待响应。
看上去貌似没啥问题吧。代码跑起来,也确实能正常收发消息。但是这段代码跑一段时间,就会出现 i/o timeout 的报错。这其实是最近排查了的一个问题,发现这个坑可能比较容易踩上,这边对代码做了简化。
实际生产中发生的现象是,golang 服务在发起 http 调用时,虽然 http.Transport
设置了 3s 超时,会偶发出现 i/o timeout 的报错。
但是查看下游服务的时候,发现下游服务其实 100ms 就已经返回了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论