Go的http.Client实例应该被重用的原因是什么?

huangapple go评论72阅读模式
英文:

Why should Go’s http.Client instances be reused?

问题

Go文档中提到:

> 客户端的传输通常具有内部状态(缓存的TCP连接),因此应该重复使用客户端而不是根据需要创建。客户端可以安全地供多个goroutine并发使用。

为什么重复使用客户端有助于保留传输的内部状态,即使我可以实例化一个传输并将其传递给单次使用的客户端实例,就像这样:

<!-- language-all: lang-go -->

client := &amp;http.Client{Transport: transport}
英文:

The Go documentation says

> The Client's Transport typically has internal state (cached TCP connections), so Clients should be reused instead of created as needed. Clients are safe for concurrent use by multiple goroutines.

Why does Client reuse help with preserving the Transport’s internal state, given that I can instantiate a transport and pass it to single-use Client instances like this:

<!-- language-all: lang-go -->

client := &amp;http.Client{Transport: transport}

答案1

得分: 1

为什么应该重用Go的http.Client实例?

有很多原因。最普遍的原因是为了允许重用现有的HTTP连接。如果你为每个请求使用一个新的http.Client实例,就无法利用现有的HTTP连接,这会导致更多的开销和较慢的性能。

另一个常见的原因是如果你调用使用cookie的HTTP服务器,可以使用cookie jar。

英文:

> Why should Go’s http.Client instances be reused?

There are many reasons. The most universal one is to allow reusing existing HTTP connections. If you use a new http.Client instance for every request, you can never take advantage of existing HTTP connections, which will result in more overhead and slower performance for most common uses.

Another common reason would be to use a cookie jar, if you're calling an HTTP server that uses cookies.

答案2

得分: 0

consul-k8s项目实际上通过创建许多短暂的Client实例来实现这一点,所有这些实例共享同一个Transport。这是在https://github.com/hashicorp/consul-k8s/commit/5672d344中完成的,可能是偶然的,因为PR只是说:

> 对端点控制器+测试中的consul客户端处理方式进行了微小的更改。

在这个微小的更改之前,它每次都创建一个新的Transport(因此泄漏了大量的连接):

localConfig := api.DefaultConfig()

更改后,它重用了相同的Transport:

localConfig := r.ConsulClientCfg

有泄漏的版本从未进入任何实际发布,所以一切都很好。

英文:

The consul-k8s project actually does this, by creating many short-lived Client instances, all sharing the same Transport. This was done in https://github.com/hashicorp/consul-k8s/commit/5672d344, perhaps accidentally as the PR just said:

> Minor change to how we deal with consul clients in the endpoints controller+tests.

Prior to this minor change, it creates a new Transport every time (and thus leaks plenty of connections):

localConfig := api.DefaultConfig()

After the change, it reuses the same Transport:

localConfig := r.ConsulClientCfg

The leaky version never made it into any actual release, so it is all good.

huangapple
  • 本文由 发表于 2022年9月19日 16:13:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/73770352.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定