在 Golang 中复用 HTTP 连接
问题提出
最近在实现一个转发大模型调用请求的中转功能,涉及到要构造client发送请求的内容,一开始我每次都是新建一个client来发送请求,这样的代码实现存在一些问题——每次都要构造新的client,并且要重新建立连接。后面了解到在Go中使用 HTTP 客户端(http.Client
)可以实现连接复用,做到提高性能并减少 TCP 连接的重复建立。
// 原始做法
client := &http.Client{Timeout: consts.GetRequestTimeout(), // 设置请求超时时间}resp, err := client.Do(req)
defer resp.Body.Close()// 修改后做法
resp, err := sharedHttpClient.Do(req)
defer resp.Body.Close()// 必须关闭 Body 才能复用连接
原理探寻
在 Go 中,HTTP 客户端默认会复用 TCP 连接,只要使用同一个 http.Client
实例,并且服务端支持 Keep-Alive。
原因是 http.Transport
内部维护了一个 连接池。只要满足以下条件就可以进行连接复用:
- 使用同一个
http.Client
。 - 响应的
Body
被正确关闭。 - 请求的 Host 相同。
Transport
会根据空闲连接数和超时管理复用,可根据需求调整Transport
相关的参数。