問題提出
最近在實現一個轉發大模型調用請求的中轉功能,涉及到要構造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
相關的參數。