gpt4 book ai didi

http - golang 获取大量读取 tcp ip :port i/o timeout in ubuntu 14. 04 LTS

转载 作者:IT王子 更新时间:2023-10-29 01:13:38 25 4
gpt4 key购买 nike

我写了一个 golang 程序,过去几个月在 ubuntu 12.04 LTS 上运行良好,直到我将它升级到 14.04 LTS

我的程序专注于发送 HTTP 请求,每秒发送大约 2-10 个 HTTP 请求。 HTTP 请求地址不同。

当问题出现时,首先,一些请求显示read tcp [ip]:[port]: i/o timeout,然后几分钟后所有请求显示read tcp [ ip]:[port]: i/o timeout,无法发送任何请求。

我重新启动程序,一切都恢复正常了。

我们所有的服务器(2台服务器)从12.04升级到14.04后都有这样的问题

我为每个请求创建新的 goroutine

问题不是在同一个时间间隔出现,有时一两天不会出现,有时一小时出现两次

下面是我请求 HTTP 地址的代码:

t := &http.Transport{
Dial: timeoutDial(data.Timeout),
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
//req := s.ParseReq(data)
req := data.convert2Request()
if req == nil {
return
}

var resp *http.Response
if data.Redirect {
c := &http.Client{
Transport: t,
}
resp, err = c.Do(req)
} else {
resp, err = t.RoundTrip(req)
}

data.updateTry()

r := s.ParseResp(data, resp, err)

更新尝试:

func (d *SendData) updateTry() {
d.Try++
d.LastSend = time.Now()
}

超时拨号:

func timeoutDial(timeout int) func(netw, addr string) (net.Conn, error) {
if timeout <= 0 {
timeout = 10
}
return func(netw, addr string) (net.Conn, error) {
deadline := time.Now().Add(time.Duration(timeout) * time.Second)
c, err := net.DialTimeout(netw, addr, time.Second*time.Duration(timeout+5))
if err != nil {
return nil, err
}
c.SetDeadline(deadline)
return c, nil
}
}

我的处理方式是:

func (s *Sender) ParseResp(data SendData, resp *http.Response, err error) (r Resp) {
r = Resp{URL: data.URL}
if err != nil {
r.Err = err.Error()
} else {
r.HttpCode = resp.StatusCode
r.Header = resp.Header
r.URL = resp.Request.URL.String()
defer resp.Body.Close()
// we just read part of response and log it.
reader := bufio.NewReader(resp.Body)
buf := make([]byte, bytes.MinRead) // 512 byte
for len(r.Body) < 1024 { // max 1k
var n int
if n, _ = reader.Read(buf); n == 0 {
break
}
r.Body += string(buf[:n])
}
}
return
}

我还发现/etc/sysctl.conf 中的设置可以降低问题发生的频率:

net.core.somaxconn = 65535
net.netfilter.nf_conntrack_max = 655350
net.netfilter.nf_conntrack_tcp_timeout_established = 1200

我需要帮助来解决这个问题。

似乎是这样,但我没有看到任何解决方案https://bugs.launchpad.net/juju-core/+bug/1307434

最佳答案

为了更明确地说明 Not_a_Golfer 和 OneOfOne 所说的内容,当您完成响应时,您需要关闭保持打开状态的连接(通过 io.ReadCloser 的 Body 字段)。所以基本上,一个简单的方法是将与发出 http 请求有关的代码更改为:

var resp *http.Response
if data.Redirect {
c := &http.Client{
Transport: t,
}
resp, err = c.Do(req)
} else {
resp, err = t.RoundTrip(req)
}
if err == nil {
defer resp.Body.Close() // we need to close the connection
}

关于http - golang 获取大量读取 tcp ip :port i/o timeout in ubuntu 14. 04 LTS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28528060/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com