Go文档说客户端的传输通常具有内部状态(缓存的TCP连接),因此应重用客户端,而不是根据需要创建客户端。客户端对于多个goroutine并发使用是安全的。既然我可以示例化传输并将其传递给一次性客户端示例,为什么客户端重用有助于保留传输的内部状态:
client := &http.Client{Transport: transport}
wgxvkvu91#
为什么要重用Go语言的http.client示例?原因有很多。最通用的一种是允许重用现有的HTTP连接。如果对每个请求都使用新的http.Client示例,则永远无法利用现有的HTTP连接,这将导致更多的开销和大多数常见用途的性能下降。另一个常见的原因是使用cookie jar,如果您调用使用cookie的HTTP服务器。
http.Client
zqdjd7g92#
consul-k8s项目实际上就是这样做的,它创建了许多短期客户端示例,所有示例都共享相同的Transport。这是在https://github.com/hashicorp/consul-k8s/commit/5672d344中完成的,可能是偶然的,正如PR所说:在端点控制器+测试中处理consul客户端的方式的微小更改。在这个小改动之前,它每次都会创建一个新的Transport(因此会泄漏大量的连接):
localConfig := api.DefaultConfig()
更改后,它将重用相同的Transport:
localConfig := r.ConsulClientCfg
泄漏的版本从来没有使它成为任何实际的释放,所以这一切都是好的。
2条答案
按热度按时间wgxvkvu91#
为什么要重用Go语言的http.client示例?
原因有很多。最通用的一种是允许重用现有的HTTP连接。如果对每个请求都使用新的
http.Client
示例,则永远无法利用现有的HTTP连接,这将导致更多的开销和大多数常见用途的性能下降。另一个常见的原因是使用cookie jar,如果您调用使用cookie的HTTP服务器。
zqdjd7g92#
consul-k8s项目实际上就是这样做的,它创建了许多短期客户端示例,所有示例都共享相同的Transport。这是在https://github.com/hashicorp/consul-k8s/commit/5672d344中完成的,可能是偶然的,正如PR所说:
在端点控制器+测试中处理consul客户端的方式的微小更改。
在这个小改动之前,它每次都会创建一个新的Transport(因此会泄漏大量的连接):
更改后,它将重用相同的Transport:
泄漏的版本从来没有使它成为任何实际的释放,所以这一切都是好的。