去http.Get,并发,"连接由同行重置"

时间:2016-06-12 13:09:09

标签: http go concurrency

我有1000-2000个网页可以从一台服务器上下载,我正在使用go例程和渠道来实现高效率。问题是,每次运行我的程序时,最多400个请求都会因错误而失败,并且#34;连接由peer"重置。很少(可能是10次中的1次),没有请求失败。

我该怎么做才能防止这种情况发生?

有趣的是,当我在与托管网站的服务器相同的国家/地区的服务器上运行此程序时,0请求失败,因此我猜测延迟存在一些问题(因为它现在是在另一个大陆的服务器上运行。)

我使用的代码基本上只是一个简单的http.Get(url)请求,没有额外的参数或自定义客户端。

4 个答案:

答案 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?