我收到了很多错误,如下所述,
阅读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次请求,我有 500ms的时间范围来获取第三方API的响应。
来自我的服务器的netstat状态(使用:netstat -nat | awk&#39; {print $ 6}&#39; | sort | uniq -c | sort -n)获取频率< / p>
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
答案 0 :(得分:2)
当通过互联网以高速率建立连接时,您很可能会遇到某些连接问题。您无法完全缓解它们,因此您可能希望在请求周围添加重试逻辑。此时的实际错误类型可能无关紧要,但匹配use of closed network connection
或connection reset by peer
的错误字符串是您可以做的最佳选择。确保通过退避来限制重试,因为某些系统会丢弃或重置连接以限制请求率,并且您重新连接的速度越快,可能会出现更多错误。
根据您正在与之通信的远程主机的数量,您需要增加Transport.MaxIdleConnsPerHost
(默认值仅为2)。与您交谈的主机越少,您设置的越多。这将减少新连接的数量,并加快整体请求。
如果可以,请尝试使用go1.5测试版。围绕保持活动连接进行了一些更改,可能有助于减少您看到的错误数量。
答案 1 :(得分:2)
我建议在电线侧面实施指数退避或其他速率限制机制。对于这些错误,您无法做任何事情,并且使用指数退避不一定会使您更快地获取数据。但它可以确保您获得所有数据,并且您从中获取的API肯定会降低流量。这是我在GitHub上找到的链接; https://github.com/cenkalti/backoff
虽然我还没有使用过,但还有另一种受欢迎的选择。自己实施一个也不是非常困难,我可以根据要求提供一些样本。根据我的经验,我建议做的一件事是确保您使用具有中止通道的重试功能。如果你真的很长时间退缩,那么你会想让呼叫者有一些方法来杀死它。