我有1000-2000个网页可以从一台服务器上下载,我正在使用go例程和渠道来实现高效率。问题是,每次运行我的程序时,最多400个请求都会因错误而失败,并且#34;连接由peer"重置。很少(可能是10次中的1次),没有请求失败。
我该怎么做才能防止这种情况发生?
有趣的是,当我在与托管网站的服务器相同的国家/地区的服务器上运行此程序时,0请求失败,因此我猜测延迟存在一些问题(因为它现在是在另一个大陆的服务器上运行。)
我使用的代码基本上只是一个简单的http.Get(url)请求,没有额外的参数或自定义客户端。
答案 0 :(得分:14)
消息connection reset by peer
表示远程服务器发送RST
强制关闭连接,故意作为限制连接的机制,或者由于缺乏资源。无论哪种方式,您可能打开太多连接,或重新连接太快。
并行启动1000-2000连接很少是下载那么多页面的最有效方式,特别是如果大多数或全部来自单个服务器。如果测试吞吐量,您会发现最低的并发级别。
您还需要将Transport.MaxIdleConnsPerHost
设置为与您的并发级别相匹配。如果MaxIdleConnsPerHost
低于预期的并发连接数,则服务器连接通常会在请求后关闭,只会立即再次打开 - 这会显着降低您的进度并可能达到服务器强加的连接限制。
答案 1 :(得分:14)
仍然是一个golang新手,希望这会有所帮助。
var netClient = &http.Client{}
func init() {
tr := &http.Transport{
MaxIdleConns: 20,
MaxIdleConnsPerHost: 20,
}
netClient = &http.Client{Transport: tr}
}
func foo() {
resp, err := netClient.Get("http://www.example.com/")
}
答案 2 :(得分:2)
通过在运输上设置MaxConnsPerHost
选项,我获得了不错的成绩...
cl := &http.Client{
Transport: &http.Transport{MaxConnsPerHost: 50}
}
MaxConnsPerHost可以选择限制每个主机的连接总数,包括处于拨号,活动和空闲状态的连接。违反限制时,拨号会阻塞。
https://golang.org/pkg/net/http/#Transport.MaxConnsPerHost
编辑:为明确起见,此选项在Go 1.11中发布,在上述@ AG1或@JimB的回答时不可用,因此我将其发布了。
答案 3 :(得分:1)
从中下载网页的服务器可能有某种类型的限制机制,它可以防止每秒/(或类似)超过一定数量的请求来自某个IP?尝试限制为每秒100个请求或在请求之间添加睡眠。 通过对等方重置连接基本上是服务器拒绝您的服务。 (What does "connection reset by peer" mean?)