GOLANG,HTTP有;“使用封闭网络连接”;错误

GOLANG,HTTP有;“使用封闭网络连接”;错误,http,tcp,go,Http,Tcp,Go,我犯了很多错误,就像下面提到的 阅读tcp xx.xx.xx.xx:80:使用封闭网络连接 阅读tcp xx.xx.xx.xx:80:对等方重置连接 //用于HTTP连接的函数 func GetResponseBytesByURL_raw(restUrl, connectionTimeOutStr, readTimeOutStr string) ([]byte, error) { connectionTimeOut, _ /*err*/ := time.ParseDuration(con

我犯了很多错误,就像下面提到的

阅读tcp xx.xx.xx.xx:80:使用封闭网络连接

阅读tcp xx.xx.xx.xx:80:对等方重置连接

//用于HTTP连接的函数

func GetResponseBytesByURL_raw(restUrl, connectionTimeOutStr, readTimeOutStr string) ([]byte, error) {
    connectionTimeOut, _ /*err*/ := time.ParseDuration(connectionTimeOutStr)
    readTimeOut, _ /*err*/ := time.ParseDuration(readTimeOutStr)
    timeout := connectionTimeOut + readTimeOut // time.Duration((strconv.Atoi(connectionTimeOutStr) + strconv.Atoi(readTimeOutStr)))
    //timeout = 200 * time.Millisecond
    client := http.Client{
        Timeout: timeout,
    }
    resp, err := client.Get(restUrl)
    if nil != err {
        logger.SetLog("Error GetResponseBytesByURL_raw |err: ", logs.LevelError, err)
        return make([]byte, 0), err
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    return body, err
}
更新(7月14日):

服务器:NumCPU=8,RAM=24GB,GO=go1.4.2.linux-amd64

在交通繁忙的时候,我犯了这样的错误。 每分钟20000-30000个请求,我有一个500毫秒的时间框架从第三方api获取响应。

netstatstatus从我的服务器(使用:netstat-nat | awk'{print$6}'| sort | uniq-c | sort-n)获取频率

      1 established)
      1 Foreign
      9 LISTEN
     33 FIN_WAIT1
    338 ESTABLISHED
   5530 SYN_SENT
  32202 TIME_WAIT
sysctl-p

**sysctl -p**
fs.file-max = 2097152
vm.swappiness = 10
vm.dirty_ratio = 60
vm.dirty_background_ratio = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.ip_local_port_range = 2000 65535
net.ipv4.tcp_rfc1337 = 1
net.ipv4.tcp_fin_timeout = 5
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 15
net.core.rmem_default = 31457280
net.core.rmem_max = 12582912
net.core.wmem_default = 31457280
net.core.wmem_max = 12582912
net.core.somaxconn = 65536
net.core.netdev_max_backlog = 65536
net.core.optmem_max = 25165824
net.ipv4.tcp_mem = 65536 131072 262144
net.ipv4.udp_mem = 65536 131072 262144
net.ipv4.tcp_rmem = 8192 87380 16777216
net.ipv4.udp_rmem_min = 16384
net.ipv4.tcp_wmem = 8192 65536 16777216
net.ipv4.udp_wmem_min = 16384
net.ipv4.tcp_max_tw_buckets = 1440000
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv6.bindv6only = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
error: "net.ipv4.icmp_ignore_bogus_error_messages" is an unknown key
kernel.exec-shield = 1
kernel.randomize_va_space = 1
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0

当通过internet高速连接时,很可能会遇到一些连接问题。您无法完全缓解它们,因此您可能需要在请求周围添加重试逻辑。此时的实际错误类型可能无关紧要,但如果您想具体说明,那么匹配
使用封闭网络连接
对等方重置连接的错误字符串是最好的选择。请确保使用回退限制重试次数,因为某些系统会断开或重置连接以限制请求速率,并且重新连接越快,您可能会收到更多错误

根据要与之通信的远程主机的数量,您将需要增加Transport.MaxIdleConnsPerHost(默认值仅为2)。与的主机越少,您可以设置的越高。这将减少新连接的数量,并加快总体请求速度


如果可以,试试go1.5测试版。在保持活动连接方面已经有了一些变化,这可能有助于减少您看到的错误数量。

我建议在您这方面实施指数退避或其他一些速率限制机制。对于这些错误,您实在无能为力,使用指数回退也不一定能让您更快地获取数据。但它可以确保您获得所有数据,并且您所使用的API肯定会欣赏减少的流量。这是我在GitHub上找到的一个链接


还有另一个流行的选择,虽然我也没有用过。自己实现一个也不是非常困难,我可以根据要求提供一些示例。根据我的经验,我推荐的一件事是确保您使用的重试函数具有中止通道。如果您需要很长的回退时间,那么您需要一些方法让调用者终止它。

看起来服务器正在关闭没有适当内容长度头的连接。您是否检查了返回的标题和内容?您的请求速率是多少/大约每分钟要提取多少数据?我只在hodge podge的限速问题上收到过这样的回复……正如其他人所说,这是因为服务器正在关闭连接。我遇到的其他可能原因:服务器有一个超时,它会在您发出下一个请求的同时持续关闭连接,或者是一个糟糕的反向代理/服务器组合,在没有
连接的情况下错误地关闭请求:close
头。@evanmcdonnal在中添加了详细信息questions@JimB我也这么认为,但我不确定,你说的是:body,err:=getresponsebytes-byerl\u raw(url,t1,t2);如果nil!=err{body,err=GetResponseBytesByURL_raw(url,t1,t2)}@niraj.nijju:我不确定这是做什么的,但这可能是测试重试的一种简单方法。我寻找了MaxIdleConnsPerHost,我应该使用它,但我对该方法感到困惑,请建议一种方法@niraj.nijju:没有理由每次都创建一个新的客户端和传输。它不仅浪费资源,而且您将无法重用它在您的第二个示例中,由于某种原因(尽管语法错误),您两次初始化
client
。对于您的传输,请查看http.DefaultTransport的配置;您可能需要一个类似的拨号器和TLSHandshakeTimeout。好消息是,go 1.16中已经解决了这一问题。因为我必须在500毫秒内返回响应,否则我的客户将不关心我的响应,并自行决定,因此我不能使用大的回退插槽,但如果在200毫秒内失败,请使用重试。(这可能会增加峰值期间的负载,但让我试试。)